【问题标题】:Why im getting exception error indexOutOfRangeException?为什么我收到异常错误 indexOutOfRangeException?
【发布时间】:2013-09-11 00:42:55
【问题描述】:

在 Form1 构造函数中我有:

if (System.IO.File.Exists(keywords_path_file))
            {
                ListBoxLoadKeys(LocalyKeyWords, keywords_path_file);
            }
            else
            {
                fileExist = new StreamWriter(keywords_path_file);
                fileExist.Close();
                ListBoxLoadKeys(LocalyKeyWords, keywords_path_file);
            }

我使用断点并查看文件是否存在:

C:\Users\bout0_000\AppData\Local\GatherLinks\GatherLinks\Keywords\Keywords.txt

文件内容为:

http://www.walla.co.il,walla
http://www.cnet.com,cnet
http://rotter.net/forum/scoops1/29961.shtml,rotter
http://vanessawest.tripod.com/crimescenephotos.html,VanessaWest
http://rotter.net/forum/scoops1/45227.shtml,scoops
https://www.google.com/search?q=live+cameras,live camera
https://www.google.com/search?q=rape+images&oq=+images&aqs=chrome..69i57.1661j0&sourceid=chrome&ie=UTF-8,hi
https://www.google.com/search?q=+images&um=1&ie=UTF-8&hl=en&tbm=isch&source=og&sa=N&tab=wi&ei=GqotUv2kA4OftAae94DoAg&biw=951&bih=457&sei=oaotUtDqM8WbtAag3IFg#hl=en&q=+and+&tbm=isch&um=1,chud
http://www.test.com,test

该文件包含 9 个键和关键字。左边是键,右边是关键字。

然后进入这个方法:

private void ListBoxLoadKeys(Dictionary<string, List<string>> dictionary, string FileName)
        {
            List<string> urls = new List<string>();
            using (StreamReader sr = new StreamReader(FileName))
            {
                while ((line = sr.ReadLine()) != null)
                {
                    int i = line.Count();
                    tokens = line.Split(',');
                    dictionary.Add(tokens[0], tokens.Skip(1).ToList());
                    data.Add("Url: " + tokens[0] + " --- " + "Localy KeyWord: " + tokens[1]);
                    urls.Add(tokens[0]);
                }
            }
            listBox1.DataSource = data;
            listBox1.Tag = urls;
        }

在其出线时的方法中:listBox1.DataSource = data;它的跳跃和做这个事件:

private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {

            if (listBox1.SelectedItem != null)
            {
                label4.Text = listBox1.SelectedItem.ToString();
                string startTag = "Url: ";
                string endTag = " ---";
                int startTagWidth = startTag.Length;
                int endTagWidth = endTag.Length;
                int index = 0;
                index = label4.Text.IndexOf(startTag, index);
                int start = index + startTagWidth;
                index = label4.Text.IndexOf(endTag, start + 1);
                string g = label4.Text.Substring(start, index - start);
                label4.Text = g;
                mainUrl = g;
            }
        }

最后我看到 data 和 listBox1.DataSource 都包含 9 个项目。

在这一切之后,程序正在运行。 我在 listBox 的右侧看到了键和关键字的项目。 一旦我点击了 listBox1 中的一个键,我就遇到了异常:

if (listBox1.SelectedItem != null)

在 listBox1_SelectedIndexChanged 事件中。

例外是:

索引超出了数组的范围

System.IndexOutOfRangeException was unhandled
  HResult=-2146233080
  Message=Index was outside the bounds of the array.
  Source=System.Windows.Forms
  StackTrace:
       at System.Windows.Forms.ListBox.ItemArray.GetItem(Int32 virtualIndex, Int32 stateMask)
       at System.Windows.Forms.ListBox.get_SelectedItem()
       at GatherLinks.Form1.listBox1_SelectedIndexChanged(Object sender, EventArgs e) in d:\C-Sharp\GatherLinks\GatherLinks-2\GatherLinks\GatherLinks\Form1.cs:line 543
       at System.Windows.Forms.ListBox.OnSelectedIndexChanged(EventArgs e)
       at System.Windows.Forms.ListBox.WmReflectCommand(Message& m)
       at System.Windows.Forms.ListBox.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.SendMessage(HandleRef hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       at System.Windows.Forms.Control.SendMessage(Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.Control.ReflectMessageInternal(IntPtr hWnd, Message& m)
       at System.Windows.Forms.Control.WmCommand(Message& m)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
       at System.Windows.Forms.ContainerControl.WndProc(Message& m)
       at System.Windows.Forms.Form.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       at System.Windows.Forms.NativeWindow.DefWndProc(Message& m)
       at System.Windows.Forms.Control.DefWndProc(Message& m)
       at System.Windows.Forms.Control.WmKillFocus(Message& m)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ListBox.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
  InnerException: 

我知道异常是什么意思,但我得到它是什么意思,我该如何解决?

例如,如果我在运行程序时首先移动,使用向上和向下的键箭头在列表框中的键之间移动,然后单击其中一个键,我没有得到任何异常。 当我运行程序并立即用鼠标单击列表框中的一个键时,会出现异常。

在它们之间移动然后单击其中一个是可以的,但首先单击其中一个会导致异常。

编辑**

我现在看到,在它去 listBox1_SelectedIndexChanged 事件之前,这个事件 istBox1 鼠标按下:

private void listBox1_MouseDown(object sender, MouseEventArgs e)
        {
            if (Control.ModifierKeys == Keys.Control || ( Control.ModifierKeys == Keys.Control || e.Button == MouseButtons.Left))
            {
                listBox1.SelectionMode = SelectionMode.MultiExtended;
            }
            else if (e.Button == MouseButtons.Left)
            {
                listBox1.SelectionMode = SelectionMode.One;
            }
        }

做这行:

listBox1.SelectionMode = SelectionMode.MultiExtended;

然后回到selectedindexchanged事件,抛出异常就行了:

if (listBox1.SelectedItem != null)

那也是行号:543

【问题讨论】:

  • 在调试模式下,处理这个异常的行是什么?
  • 不确定,但label4.Text.Substring(start, index - start); 很可疑。
  • 线543是什么?不知道哪个方法可以抛出IndexOutOfRangeException,但在您的代码中它发生在lisbox1_SelectedIndexChanged 中,只需在此处放置一个断点并逐步检查问题所在。
  • 看来您正在使用ListBox 控件执行多线程操作。是吗?
  • 更新了我现在看到的问题,首先它执行 listBox mousedown 事件,然后返回 selectedindexchanged 事件,然后抛出异常。

标签: c# winforms


【解决方案1】:

你不能这样做:

private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
  if (Control.ModifierKeys == Keys.Control || ( Control.ModifierKeys == Keys.Control || e.Button == MouseButtons.Left))
  {
    listBox1.SelectionMode = SelectionMode.MultiExtended;
  }
  else if (e.Button == MouseButtons.Left)
  {
    listBox1.SelectionMode = SelectionMode.One;
  }
}

我认为,在 MouseDown 事件中更改该属性会破坏窗口并重新创建它,这会混淆 SelectedIndexChanged 事件期间触发的内部信息。

只需注释掉该代码并在设计时决定 ListBox 控件应具有哪种 SelectionMode。

您还应该确保获得正确的索引值,例如:

index = label4.Text.IndexOf(endTag, start + 1);
if (index > -1) {
  string g = label4.Text.Substring(start, index - start);
  label4.Text = g;
}

【讨论】:

  • 不只是“我认为”。它在 SelectionMode 设置器中调用 Control.RecreateHandle()!
【解决方案2】:

这是反编译的代码,在这种情况下,stateMask 是标识所选项目的状态掩码。

public object GetItem(int virtualIndex, int stateMask)
{
  int actualIndex = this.GetActualIndex(virtualIndex, stateMask);
  if (actualIndex == -1)
    throw new IndexOutOfRangeException();
  else
    return this.entries[actualIndex].item;
}

所以必须改变一些事情,因为正如 Sriram 指出的那样,SelectedItem 属性中有以下检查:

public object SelectedItem
{
  get
  {
    if (this.SelectedItems.Count > 0)
      return this.SelectedItems[0];
    else
      return (object) null;
  }
}

所以它以某种方式通过了这里,然后在GetItem 上失败了。我怀疑有些线程是愚蠢的。

【讨论】:

  • 你确定吗?这是反编译后的代码public object SelectedItem { get { if (this.SelectedItems.Count &gt; 0) { return this.SelectedItems[0]; } return null; } }
  • 是的,这是一个很好的观点,我最初误读了。因此,该检查和GetItem 代码之间肯定发生了一些变化。多线程可能吗?
  • 是的,我在 cmets 中也问过同样的问题。我怀疑 OP 正在另一个线程中进行修改
  • 我相应地更新了我的答案,尽管它不再是一个真正的答案。谢谢@SriramSakthivel
  • 这是winform代码,不能有其他线程修改控件,因为这会导致不同的异常。
【解决方案3】:

好的,我对此进行了一些研究,可以得出结论,问题可能不在于您提供给我们的任何代码,而在于其他问题。我不赞成多线程正在运行的建议,因为 WinForm 中的多线程是非法的并且会导致不同的异常。

您需要做的 user2760148 是向我们提供small but complete example。创建一个新项目并以相同的结果实现尽可能少的代码。

您的第一步是对列表框的数据进行硬编码,然后使用 mouseDown 事件处理程序。然后慢慢地添加你的代码,直到你发现问题。您可能会自己发现问题……至少您会找到导致问题的步骤。目前这个例子中的“噪音”太多,我们不容易找到具体问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-15
    • 1970-01-01
    相关资源
    最近更新 更多