在做俄罗斯方块的时候写了下面一段代码:

private void listView1_SelectedIndexChanged(object sender, EventArgs e)         {             string strsel = this.listView1.SelectedItems[0].Text;             for (int i = 0; i < strsel.Length; i++)             {                 bArray[i / 5, i % 5] = (strsel[i] == '1') ? true : false;             }             this.label1.Invalidate();          }

就是在右边的ListView中选中一行,就在左边还原为砖块图案。但是当我第一次选择一行时没有什么问题,当我第二次选择一行时就出现下面的错误:

未处理ArgumentOutOfRangeException

InvalidArgument=“0”的值对于“index”无效。           参数名: index

上网查找说是要加一句判断

if(listView1.SelectedItems.Count > 0)

{

}

但是我不知道为什么要加这句判断。于是决定自己去寻找答案..........

经过多次测试,发现一个“秘密”。我新建了一个工程,窗体中只放了一个ListView,然后在SelectedIndexChanged事件中只加了一句代码:

private void listView1_SelectedIndexChanged(object sender, EventArgs e)             {             int c=this.listView1.SelectedItems.Count;            }

目的是想看一下c=this.listView1.SelectedItems.Count的变化情况,第一次选择一行的时候,c=1,第二次选择一行的时候,执行了两遍SelectedIndexChanged事件,第一遍c=0,第二遍c=1,错误的根源就在第一遍执行SelectedIndexChanged事件的过程中。

然后我又选择多行进行测试,比如3行,那么SelectedIndexChanged事件就执行了4遍,第一遍c=0,第二遍c=1,第三遍c=2,第四遍c=3。

从上面的测试我得出了以下结论:

当第二次选择一行的时候,他是先把前一次选中的那一行取消,取消之后选中的行数c=this.listView1.SelectedItems.Count就变为了0(这时SelectedItems中没有内容,而去引用它,当然会出错),然后再去选中我们要选中的行,此时c=this.listView1.SelectedItems.Count又变为了1,即选中了一行。选择多行的时候也是类似的,一个看似很简单的过程事实是分多步进行的。这就是错误的根源所在,所以我们在引用SelectedItems的时候要先做一个判断,看SelectedItems.Count是否大于0。

任何错误都是有它的原因的,只要我们坚持就一定能够找到错误的根源。

05-11 15:20