InvalidArgument = значение '0' недопустимо .. при нажатии после ComboBox.Items.Clear () - .NET - PullRequest
2 голосов
/ 21 марта 2011

Я получаю следующее необработанное исключение в конкретном случае, и я не могу понять, почему или остановить его:

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);
}

1 Ответ

2 голосов
/ 21 марта 2011

Есть ли здесь какая-то перекрестная многопоточность?

Я имею в виду ... как я обновил список.Есть ли диски, которые отображаются в списке, они должны быть присоединены, как вы говорите, и если их нет в списке, то они не должны быть доступны?

Два варианта:

  1. Поскольку список обновляется асинхронно.Правильным решением было бы убедиться, что поле со списком отключено , прежде чем ваш асинхронный метод обновит его.После обновления он должен затем включить его снова.

  2. Почему бы не отключить поле со списком, когда все ваши диски отсоединены?

Вы также можетехотите убедиться, что ваш асинхронный метод не добавляет случайно элементы один за другим на лету.Я мог видеть, что проблема заключается в том, что пользователь выпадает из поля со списком во время его обновления.Возможно, вы захотите отключить поле со списком >> Затем очистите все свои диски и добавьте их в список.

...