我在特定情况下遇到以下未处理的异常,我似乎无法解决原因或阻止它:
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);
}
答案 0 :(得分:2)
这里是否有一些交叉线程?
我的意思是......我如何更新清单。是否有列表中显示的驱动器,它们应该按照您的说法附加,如果它们不在列表中,那么它应该不可访问?
两个选项:
由于列表已更新为异步。在异步方法更新之前,一个正确的解决方案是确保组合框禁用。更新后,它应该再次启用它。
为什么不在分离所有驱动器时禁用组合框?
您可能还希望确保异步方法不会随意逐个附加项目。我可以看到,一个问题是用户在更新时会放下组合框。您可能想要禁用组合框&gt;&gt;然后清除所有驱动器并将其添加到列表中。