Обновление ListView из потока, а не из исходного потока в C#
Я уже знаю, что для обновления управления я могу использовать Invoke Action
progressBar1.Invoke(new Action(() => { progressBar1.Maximum = 0; }));
Но это только работа со свойством контроля, которые являются единичными данными. Теперь у меня есть ветка, в которой нужно изменить коллекцию представлений списка, просмотреть ее, очистить, а затем обновить новыми элементами, новыми текстами и изображениями значков. Чем они отличаются, целое число или логическое сравнение по сравнению со списком, массивом или коллекцией целочисленного, логического или даже компонентного элемента управления. Могу ли я просто добавить
string[] newItemText = {"item1", "item2", ...};
listView1.Invoke(new Action() => {
i = 0;
foreach(var item in listView1.Items)
{
item.Text = newItemText[i];
i++;
}
}));
Мне может понадобиться решение для представления моего списка, но если у вас есть ответ, пожалуйста, четко объясните, почему и как он работает, потому что мне нужно подробно узнать об этом. Также вы можете заметить меня о риске при попытке этой практики.
РЕДАКТИРОВАТЬ: Вопрос не в том, как обновить элемент управления из другого потока. О том, когда и почему нужно это делать, а не к тому. Более того, мне нужно знать разницу между обновлением отдельных данных и обновлением всей коллекции данных.
1 ответ
Нет разницы в обновлении значения или добавлении дополнительных элементов в список.
Внутренне происходит то, что графические ресурсы, используемые для рисования в Windows (это также может быть применено к Android), требуют использования ручек, кистей и объектов такого типа.
Эти объекты принадлежат контексту потока, в котором они были изначально созданы. Обычно это происходит в основном потоке, но если вы создадите графический объект, в данном случае List, в отдельном потоке, отличном от основного, этот конкретный поток будет потоком-владельцем вашего элемента управления.
Если вы хотите что-то изменить в элементе управления, что требует обновления пользовательского интерфейса (требует использования перьев, кистей и т. Д.), Вы должны сделать это из того же потока, который "владеет" вашим элементом управления. Вот почему вам нужно использовать Invoke.
Это главный принцип. Если вы обновите скалярное значение как Integer или добавите элементы в список, различий не будет. Оба требуют использования графических ресурсов, поэтому оба требуют вызова из того же потока, который владеет элементом управления.
Дайте мне знать, если это понятно.
Редактировать. В любом случае ваш код выглядит немного странно, потому что вы заполняете список итерациями из собственного списка. Не будет ли больше смысла делать это?
string[] newItemText = {"item1", "item2", ...};
listView1.Invoke(new Action() => {
for(int i = 0; i < newItemText.length; i++)
{
listView1.add(newItemText[i]);
}
});
не зная остального контекста, для меня это звучит более логично.