为什么我开了这么多贴还是没解决啊,就要崩溃了,现在总结在这一贴里,谁帮我解决了赠全部分,跪求了
说一下我的思路:先看下面已经显示出来的datagrid,编号是标识列,int自动编号,数据库sql2000
编号 姓名 球队 位置 上轮得分 总分 买入统计 卖出统计 评论 身价(万)
21 汉母 阿深那 前锋 10 20 2 1 查看 2300 购买
20 贝壳 阿深那 前锋 10 20 1 1 查看 2200 购买
5 贝母 曼联 前锋 10 20 1 1 查看 2400 购买
4 母3 曼联 守门员 10 20 1 1 查看 2300 购买
1 2 3 4 5
现在我要点购买后将对应那一行的球员插入另一个数据表exchange,而先要验证那个exchange表中是否已经存在这个球员。那么我先要获得对应行的球员的编号,然后进行查询
<asp:datagrid id="player_list" runat="server" AllowPaging="True" PageSize="5" OnPageIndexChanged="player_list_Page" DataKeyField="player_id" OnItemCommand="buy_player">
<Columns>
这个是编号列,在第一列
<asp:BoundColumn DataField="player_id" HeaderText="编号"></asp:BoundColumn>
这个是购买按钮列,在第11行
<asp:ButtonColumn Text="购买" ButtonType="PushButton" CommandName="buy_player"></asp:ButtonColumn>
下面是按钮列对应的代码
public void buy_player(object sender, DataGridCommandEventArgs e)
{
int j=0;
int user_id=(int)Session["user"];
出错行####
int player_id=Convert.ToInt32(player_list.DataKeys[(int)e.Item.ItemIndex]);
####
if(j==0)
{//判断球员是否已经买入
String SQL_w="Select * from exchange where user_id=@user_id and player_id=@player_id ";
SqlCommand cmd_w=new SqlCommand(SQL_w,Conn);
cmd_w.Parameters.Add(new SqlParameter("@player_id",SqlDbType.Int,4));
cmd_w.Parameters["@player_id"].Value =player_id;
cmd_w.Parameters.Add(new SqlParameter("@user_id",SqlDbType.Int,4));
cmd_w.Parameters["@user_id"].Value =user_id;
Conn.Open();
SqlDataReader reader_w = cmd_w.ExecuteReader();
if(reader_w.Read())
{
j=1;
}
else{j=0;}
reader_w.Close();
Conn.Close();
}
运行并没有错,但当我点datagrid的第2页时就会报错,出错的那一行就是为了获得datagrid的主建值球员编号,也就是DataKeyField="player_id"
那么它的错误信息是这样的
####
索引超出范围。必须为非负值并小于集合大小。参数名: index
int player_id=Convert.ToInt32(player_list.DataKeys[(int)e.Item.ItemIndex]);
####
于是我想既然这个player_id已经显示出来了,那我就将这个显示出来的值赋给int player_id是一样啊
于是改成这样
int player_id=Convert.ToInt32(e.Item.Cells[0].Text);
那现在的错误又变成了这样的
输入字符串的格式不正确
int player_id=Convert.ToInt32(e.Item.Cells[0].Text);
该怎么解决啊,我以前写编辑和删除按钮时也用过DataKeys[(int)e.Item.ItemIndex]);却没出过错啊
问题点数:100、回复次数:16Top
1 楼qsoo(求 索)回复于 2004-09-03 13:52:44 得分 0
而我删掉这个购买按钮事件时分页又正常Top
2 楼acewang(龍芯*Inside!)回复于 2004-09-03 13:55:34 得分 10
if (e.CommandName="buy_player")
{
int player_id=Convert.ToInt32(player_list.DataKeys[(int)e.Item.ItemIndex]);
...
}Top
3 楼qsoo(求 索)回复于 2004-09-03 13:59:43 得分 0
acewang(龍芯*Inside!)
为什么要这样写,加在哪?Top
4 楼triout(笨牛)回复于 2004-09-03 14:08:18 得分 60
看了你的问题,大致明白了你的意思和问题所在。
下面讲一下我的看法。
错误:
索引超出范围。必须为非负值并小于集合大小。参数名: index
int player_id=Convert.ToInt32(player_list.DataKeys[(int)e.Item.ItemIndex]);
因为我很少用到DATAKEYS或者用到DATAKEYS也没有使用分页,所以你这样的问题还没有遇到过(我对DATAGRID的分页功能是抵触的,都是通过代码实现分页后处理)。
对于你的这个问题,我想你可以先输出e.Item.ItemIndex是什么值。从你的问题来看,在第一页是没有问题的,到第二页就有问题了,那么说明DATAGRID的DATAKEYS中存储的数据是当前页面的数据,而e.Item.ItemIndex的值是整个DATAGRID中所有页面的索引,比如,你点击第二页第一行,页面大小是10,则e.Item.ItemIndex的值是11了,而DataKeys的Count最多只有10,所以报告了你的错误。
解决:
先检测e.Item.ItemIndex的值是否如我所说,如是则按照我的说法,把这个值减去页码*页面大小,如果不是则把你的检测结果贴出来后通知我吧。
错误:
于是改成这样
int player_id=Convert.ToInt32(e.Item.Cells[0].Text);
那现在的错误又变成了这样的
输入字符串的格式不正确
int player_id=Convert.ToInt32(e.Item.Cells[0].Text);
如果e.Item.Cells[0].Text的值是一个可以转换为数值的字符串,那么这个语句是不会报告错误的。但你的代码却报告错误了,为什么?原因只有一个:这个字符串是不能转换为数值。
有时候DATAGRID会难以预料的生成一些我们感到很困惑的代码,估计这就是你这个问题的原因了。
解决:
先检测一下e.Item.Cells[0].Text的内容,然后再判断,如果不是编号,检测e.Item.Cells[1].Text看,一直到能找到为止。Top
5 楼triout(笨牛)回复于 2004-09-03 14:11:29 得分 0
回复人: acewang(龍芯*Inside!) ( ) 信誉:180 2004-09-03 13:55:00 得分: 0
if (e.CommandName="buy_player")
{
int player_id=Convert.ToInt32(player_list.DataKeys[(int)e.Item.ItemIndex]);
...
}
这个写法是把DataKeys中的内容转换为整数,因为DataKeys中存储的是object对象。
不过从你的问题来看,应该跟这个没有关系。Top
6 楼passacaglia(神秘园)回复于 2004-09-03 14:11:29 得分 20
int player_id=Convert.ToInt32(e.Item.Cells[0].Text);
那现在的错误又变成了这样的
输入字符串的格式不正确
看一下html里的源码不就知道到底是不是个数字了Top
7 楼passacaglia(神秘园)回复于 2004-09-03 14:15:29 得分 0
你分页到第2页的错误,看看是不是在类似ItemDataBound的事件里忘记加上
if(e.Item.ItemType==ListItemType.Item||e.Item.ItemType==ListItemType.AlternatingItem)
了Top
8 楼pgwron(情伤无痕)回复于 2004-09-03 14:32:48 得分 0
心情很不好,没分也顶Top
9 楼acewang(龍芯*Inside!)回复于 2004-09-03 14:34:11 得分 10
设置 DataKeyField="player_id" 和CommandName="buy_player"
然后在事件:
public void buy_player(object sender, DataGridCommandEventArgs e)
if (e.CommandName="buy_player")
{
int player_id=(int)player_list.DataKeys[(int)e.Item.ItemIndex];
...
}Top
10 楼qsoo(求 索)回复于 2004-09-03 14:34:40 得分 0
我检查了一下e.Item.Cells[0].Text的值,输出来的确实是编号。Top
11 楼qsoo(求 索)回复于 2004-09-03 14:41:50 得分 0
但是我将它转化为int型int a=Convert.ToInt32(e.Item.Cells[0].Text);
却又说输入字符串的格式不正确。Top
12 楼qsoo(求 索)回复于 2004-09-03 14:51:24 得分 0
在第一页时可以将a的值显示出来 直到第2页时才出错 我估计是分页时根本没有e.Item.Cells[0].Text的值 那怎么解决呢Top
13 楼noahart(八卦小子)回复于 2004-09-03 15:07:50 得分 0
好奇怪的问题。
这样呢?Convert.ToInt32(e.Item.Cells[0].Text,10);
Top
14 楼s98(三尚)回复于 2004-09-03 15:14:08 得分 0
upTop
15 楼noahart(八卦小子)回复于 2004-09-03 15:18:13 得分 0
既然你确定e.Item.Cells[0].Text是编号,
干脆就用字符串做参数
string s=e.Item.Cells[0].Text;
然后
string strsql="Select * from exchange where player_id='"+s+"'";
Top
16 楼qsoo(求 索)回复于 2004-09-03 15:23:40 得分 0
谢谢大家终于解决了 你们知道是怎么解决的吗?气死了
我把OnItemCommand="buy_player">改成了OnDeleteCommand="DataGrid1_Delete">
然后把public void buy_player(object sender, DataGridCommandEventArgs e)
{
改成了
public void DataGrid1_Delete(object sender, DataGridCommandEventArgs e)
{
因为以前做的删除记录的分页没出错过,所以我就改成那样 只是把以前删除记录的代码改成了现在的代码Top




