public static List<zb> listzb = new List<zb>();
        public loadfile(UI _UI, string _url)
        {
            UI = _UI;
            url = _url;
            loadOK();
        }
        public void loadOK()
        {
            //清空
            listzb.Clear();
            UI.Invoke(new MethodInvoker(delegate()
             {
                 UI.nclistview.Items.Clear();
                 UI.nclistview.VirtualListSize = 0;
                 UI.nclistview.VirtualMode = false;
                 UI.nclistview.RetrieveVirtualItem -= new RetrieveVirtualItemEventHandler(listView1_RetrieveVirtualItem);
             }));
            //
            StreamReader stream = new StreamReader(url, Encoding.Default);
            string temp;
            int i = 0;
            while ((temp = stream.ReadLine()) != null)
            {
                string[] temps = temp.Split(' ');
                zb _zb = new zb();
                try
                {
                    _zb.number = int.Parse(temps[0].Substring(1, temps[0].Length - 1));
                    _zb.G = int.Parse(temps[1].Substring(1, temps[1].Length - 1));
                    _zb.X = float.Parse(temps[2].Substring(1, temps[2].Length - 1));
                    _zb.Y = float.Parse(temps[3].Substring(1, temps[3].Length - 1));
                    _zb.Z = (int)float.Parse(temps[4].Substring(1, temps[4].Length - 1));
                    i++;
                    listzb.Add(_zb);
                }
                catch (OutOfMemoryException)
                {
                    GC.Collect();
                    MessageBox.Show("内存错误");
                }
                catch (Exception)
                {
                    
                    stream.Close();
                    listzb.Clear();
                    MessageBox.Show("文本有错误!请检查!" + "\r\n" + "出错行为:" + temp, "警告!");
                    return;
                }
            }
            stream.Close();
            UI.Invoke(new MethodInvoker(delegate()
                     {
                         //一些控件的enabled属性的开关
                     }));
        }
        void listView1_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
        {
            e.Item = new ListViewItem(new string[] { listzb[e.ItemIndex].number.ToString(),
                                                     listzb[e.ItemIndex].G.ToString(),
                                                     listzb[e.ItemIndex].X.ToString(),
                                                     listzb[e.ItemIndex].Y.ToString(),
                                                     listzb[e.ItemIndex].Z.ToString()});
        }以上代码有时候有问题有时候又没问题!出现异常的代码是listView1_RetrieveVirtualItem方法内的代码:
索引超出范围。必须为非负值并小于集合大小。
参数名: index
出现这个异常的时候 listzb.Count=0,所以listzb[e.ItemIndex].number.ToString()才会出错。因为listzb.Count=0所以我怀疑导致listzb.Count=0的原因是while ((temp = stream.ReadLine()) != null)一次循环也没有,但问题是这不可能出现吧?我可以确保StreamReader stream = new StreamReader(url, Encoding.Default);是没有问题,文件也绝对有内容的!
而当我试图在
UI.Invoke(new MethodInvoker(delegate()
                     {
                         //一些控件的enabled属性的开关
                     }));
之后使用if(listzb.Count==0){...}的时候,当出错时却无法进入这个IF语句!太奇怪了!

解决方案 »

  1.   

      void listView1_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
            {
              if(listzb.Count>0)
              {if(listzb[e.ItemIndex]!=null)
               {}
              }
             }
      

  2.   

    这不是解决问题的方法吧?
    我想知道为什么有时候可以有时候又不可以?文本没有变。
    listzb.Count=0的原因应该就是没有进入while ((temp = stream.ReadLine()) != null)循环,但为什么会呢!?
      

  3.   

    不知道你的UI是怎么实现的。
    还有RetrieveVirtualItem -= new RetrieveVirtualItemEventHandler(listView1_RetrieveVirtualItem);
    这个是移除事件。
    不知道你的这个事件是怎么触发的,是不是在执行while里面的 listzb.Add(_zb);之前触发的?
    这样的话,listzb.Count肯定为0,因为你之前把它清空了。没有加过东西。
      

  4.   

    补充一下代码:UI.Invoke(new MethodInvoker(delegate()
    {
    UI.nclistview.VirtualMode = true;
    UI.nclistview.VirtualListSize = i;
    UI.nclistview.RetrieveVirtualItem += new RetrieveVirtualItemEventHandler(listView1_RetrieveVirtualItem);
    //一些控件的enabled属性的开关
    }));
      

  5.   

    现在补充了一下代码。
    事件是在while循环完才重新注册上的。while循环完了以后应该已经全部添加好了!
      

  6.   

    如果listView1被清空了,那么RetrieveVirtualItem中得到的e.ItemIndex是什么值,你验证过了吗?因为没有了任何Item,但还是需要执行那个事件的话,估计e.ItemIndex为-1了,你断点跟踪下就知道了。
      

  7.   


    问题就是在你的UI.nclistview.RetrieveVirtualItem是什么时候触发 了
      

  8.   

    好了!找到问题了,谢谢3L的提醒!
    应该先注销掉事件,然后再listzb.Clear();