Почему комбобокс удваивает свои элементы при создании? - PullRequest
0 голосов
/ 26 декабря 2018

Я создаю комбинированный список программно следующим образом:

var cbo = new ComboBox();
cbo.HandleCreated += (s, e) =>
{
    cbo.DataSource = mylist;
};

Когда я делаю вышеописанное, комбинированный список отображает двойные элементы, содержащиеся в списке.Однако, когда я делаю следующее, в выпадающем списке отображается правильное количество элементов:

var cbo = new ComboBox() {
    DataSource = mylist
};

Почему это происходит?

Ответы [ 2 ]

0 голосов
/ 26 декабря 2018

Причина

HandleCreated повышается только один раз.проблема заключается в другом, это связано с тем, что OnHandleCreated и привязка данных реализованы в ComboBox.

Вот как OnHandleCreated методComboBox работает:

  • Это сначала вызывает HandleCreated событие.(Имейте в виду, на данном этапе IsHandleCreated верно.)
  • Затем для каждого элемента в Items коллекции элемента управления отправляется CB_ADDSTRING собственное сообщение для добавленияпункт в родной поле со списком.

Вот как работает установка DataSource:

  • Для каждого элемента в DataSource сначала добавляет элемент к Items collection, затем проверяет, является ли IsHandleCreated истиной, отправляет CB_ADDSTRING собственное сообщение, чтобы добавить элемент в собственное поле со списком.

Поэтому, когда вы устанавливаете DataSource в событии HandleCreated, для каждого элемента он отправляет CB_ADDSTRING собственное сообщение дважды.

Поэтому в раскрывающемся списке вы дважды видите элементы, и в то же время Items.Count показывает правильное количество.Также, если вы щелкнете по дополнительному элементу (последняя половина элементов), вы получите индекс исключения из диапазона.

Решение

Чтобы решить проблему, вы можете воспользоваться одним из следующихoptoins:

  1. Вы можете отложить выполнение кода события HandleCreated, используя BeginInvoke

  2. В качестве другого варианта, на который можно положиться VisibleChanged событие.

Опция 1 - HandleCreated + BeginInvoke

var mylist = Enumerable.Range(1, 5).ToList();
var myvalue = 2;
var cbo = new ComboBox();
cbo.HandleCreated += (obj, args) =>
{
    BeginInvoke(new Action(() =>
    {
        cbo.DataSource = mylist;
        cbo.SelectedIndex = mylist.IndexOf(myvalue);
    }));
};
this.Controls.Add(cbo);

Опция 2 - VisibleChanged

var mylist = Enumerable.Range(1, 5).ToList();
var myvalue = 2;
var cbo = new ComboBox();
cbo.VisibleChanged+= (obj, args) =>
{
    cbo.DataSource = mylist;
    cbo.SelectedIndex = mylist.IndexOf(myvalue);
};
this.Controls.Add(cbo);
0 голосов
/ 26 декабря 2018

Этот код дублирует запись, потому что при вашей инициализации combobox он попадет в событие HandleCreated , которое добавит ваш список в combobox.Затем, после завершения инициализации, выполнение кода снова вызовет событие HandleCreated , поскольку первое, которое выполняет это событие, происходит из инициализации, а второе - из самого выполнения во время выполнения.

var cbo = new ComboBox(); //initialization
//below this comment is the event
    cbo.HandleCreated += (s, e) =>
    {
        cbo.DataSource = mylist;
    };

PS

Существует лучший способ заполнения комбинированных списков в C # WinForms;каждый элемент управления (комбинированный список, текстовое поле и т. д.) имеет свои различные события.Вы можете сначала проверить это, а не создавать свое мероприятие.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...