InvalidArgument =值为'0'无效..在ComboBox.Items.Clear()之后点击 - .NET

时间:2011-03-21 10:04:20

标签: c# .net combobox

我在特定情况下遇到以下未处理的异常,我似乎无法解决原因或阻止它:

System.ArgumentOutOfRangeException: InvalidArgument=Value of '0' is not valid for 'index'.
Parameter name: index
   at System.Windows.Forms.ComboBox.ObjectCollection.get_Item(Int32 index)
   at System.Windows.Forms.ComboBox.get_SelectedItem()
   at System.Windows.Forms.ComboBox.get_Text()
   at System.Windows.Forms.ComboBox.WmReflectCommand(Message& m)
   at System.Windows.Forms.ComboBox.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.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

有问题的ComboBox是已安装驱动器的列表,当刷新驱动器列表时,列表将被清除并重新填充。

如果软件加载0驱动器,单击ComboBox 不会产生上述错误。

如果软件加载了一个或多个附加驱动器并且在刷新期间未单击ComboBox而将其删除,则稍后单击ComboBox 不会产生错误。

如果软件连接了一个或多个驱动器并且当前显示了ComboBox的下拉列表并且删除了所有驱动器,则列表清空,但单击空框 会产生以上错误。继续并再次单击会再次导致错误。

当附加/分离驱动器时,将调用包含ComboBox的表单上的以下代码:

this.cbxDrives.Items.Clear();
foreach (Drive phone in phones)
    this.cbxDrives.Items.Add(phone);
if (this.cbxDrives.Items.Count > 1) {
    this.cbxDrives.Items.Add(SynchronisedDrive.Instance); 
    this.cbxDrives.SelectedIndex = 0;
} else if(this.cbxDrives.Items.Count == 1)
    this.cbxDrives.SelectedIndex = 0;
else
    this.DriveView.Clear();

this.cbxDrives.DisplayMember = "Name";

另外,我不知道这是否相关,因为异常只提到了基类,但重写了ComboBox以在文本旁边提供一个Icon。代码如下:

protected override void OnDrawItem(DrawItemEventArgs e)
    {

        if (e.Index >= 0 && e.Index < Items.Count)
        {
            e.DrawBackground();
            e.DrawFocusRectangle();

            Drive item;
            Rectangle bounds = e.Bounds;
            int offset = 0;

            item = (Drive)Items[e.Index];

            if (item is SynchronisedDrive)
            {
                imageList.Draw(e.Graphics, bounds.Left, bounds.Top, (int)IconIndexes.ALL);
                offset = imageList.ImageSize.Width;
            } else {
                if (item.Settings.Type == Settings.DriveTypeEnum.Headset)
                {
                    if (item.Settings.Description.StartsWith("A R"))
                    {
                        imageList.Draw(e.Graphics, bounds.Left, bounds.Top, (int)IconIndexes.RED);
                        offset = imageList.ImageSize.Width;
                    }
                    else if (item.Settings.Description.StartsWith("A B"))
                    {
                        imageList.Draw(e.Graphics, bounds.Left, bounds.Top, (int)IconIndexes.BLUE);
                        offset = imageList.ImageSize.Width;
                    }
                    else if (item.Settings.Description.StartsWith("A G"))
                    {
                        imageList.Draw(e.Graphics, bounds.Left, bounds.Top, (int)IconIndexes.GREEN);
                        offset = imageList.ImageSize.Width;
                    }
                    else if (item.Settings.Description.StartsWith("A P"))
                    {
                        imageList.Draw(e.Graphics, bounds.Left, bounds.Top, (int)IconIndexes.PURPLE);
                        offset = imageList.ImageSize.Width;
                    }
                    else if (item.Settings.Description.StartsWith("An"))
                    {
                        imageList.Draw(e.Graphics, bounds.Left, bounds.Top, (int)IconIndexes.ORANGE);
                        offset = imageList.ImageSize.Width;
                    }
                    else if (item.Settings.Description.StartsWith("A Y"))
                    {
                        imageList.Draw(e.Graphics, bounds.Left, bounds.Top, (int)IconIndexes.YELLOW);
                        offset = imageList.ImageSize.Width;
                    }
                }
                else if (item.Settings.Type == Settings.DriveTypeEnum.RemoteConsole)
                {
                    imageList.Draw(e.Graphics, bounds.Left, bounds.Top, (int)IconIndexes.REMOTE);
                    offset = imageList.ImageSize.Width;
                }
                else if (item.Settings.Type == Settings.DriveTypeEnum.LL)
                {
                    imageList.Draw(e.Graphics, bounds.Left, bounds.Top, (int)IconIndexes.LL);
                    offset = imageList.ImageSize.Width;
                }
            }

            e.Graphics.DrawString(item.Name, e.Font, new
            SolidBrush(e.ForeColor), bounds.Left + offset, bounds.Top);
        }

        base.OnDrawItem(e);
}

1 个答案:

答案 0 :(得分:2)

这里是否有一些交叉线程?

我的意思是......我如何更新清单。是否有列表中显示的驱动器,它们应该按照您的说法附加,如果它们不在列表中,那么它应该不可访问?

两个选项:

  1. 由于列表已更新为异步。在异步方法更新之前,一个正确的解决方案是确保组合框禁用。更新后,它应该再次启用它。

  2. 为什么不在分离所有驱动器时禁用组合框?

  3. 您可能还希望确保异步方法不会随意逐个附加项目。我可以看到,一个问题是用户在更新时会放下组合框。您可能想要禁用组合框&gt;&gt;然后清除所有驱动器并将其添加到列表中。