Я получаю следующее необработанное исключение в конкретном случае, и я не могу понять, почему или остановить его:
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 не вызывает вышеуказанную ошибку.
Если программное обеспечение загружается с 1 или более подключенными дисками, и они удаляются, не нажимая на ComboBox во время обновления, нажатие на ComboBox после этого не вызывает ошибки.
Если к программному обеспечению подключен 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);
}