c# - InvalidArgument= '0' 的值无效.. 在 ComboBox.Items.Clear() 之后单击 - .NET

标签 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 个驱动器,则单击组合框不会产生上述错误。

如果软件加载时连接了 1 个或多个驱动器,并且在刷新期间没有单击组合框就将它们移除,则之后单击组合框不会产生错误。

如果软件连接了 1 个或多个驱动器,并且当前显示 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 被覆盖以在文本旁边提供一个图标。其代码如下:

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. 由于列表是异步更新的。一个正确的解决方案是确保组合框在您的异步方法更新之前被禁用。更新后,它应该会再次启用它。

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

您可能还想确保您的异步方法不是在运行中随机地一个接一个地附加项目。我可以看到一个问题是用户在更新组合框时下拉了组合框。您可能想要禁用组合框 >> 然后清除所有的驱动器并将它们添加到列表中。

关于c# - InvalidArgument= '0' 的值无效.. 在 ComboBox.Items.Clear() 之后单击 - .NET,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5376111/

相关文章:

c# - 需要设置控件 anchor 属性

c# - 使用 Alphavss 的卷影复制错误

c# - Stylecop 配置文件在哪里?

c# - 获取某个字符串后的数字

c# - Sqlite数据库是否支持波斯/阿拉伯语编码?

.net - 使用正则表达式替换字符串

.net - 寻找用于生成矢量图形文件的 .NET 库

combobox - OpenUI5 : Binding sap. m.ComboBox 到 sap.ui.table.Table 中的 JSONModel() 列

Java ComboBox 与 arraylist 的关联

工具栏中的组合框