Я считаю, что проблема неэффективной перерисовки форм C # в определенных обстоятельствах рассматривается в разных местах, однако мне не удалось решить свои проблемы с помощью простых фрагментов, которые я нашел в Интернете.
Моя проблема: в форме у меня есть listView, который я связываю с пользовательским держателем данных (2 столбца, ключ и дата последнего обновления). Из разных мест мне нужно вызвать метод updateTime (ключ), который затем повторил изменения в графическом интерфейсе. Модель меняется, но мой список никогда не отображается.
У меня есть форма, содержащая ListView, которая выглядит так:
partial class VolsPane : UserControl, IGUIPane
{
private ListView listView1;
private ListModel listModel1; //ListModel is 100% homemade
...
public VolsPane()
{
...
listModel1.setList(listView1);
}
}
И класс, содержащий данные для моего listView, выглядит так:
class ListModel
{
private Dictionary<string, DateTime> Underlying;
private ListView list;
...
public ListModel(string nexusKey)
{
...
}
...
public void setList(ListView list)
{
this.list = list;
}
public void updateTime(string ric)
{
Underlying[ric] = DateTime.UtcNow;
updateView();
}
public void updateView()
{
this.list.Clear();
this.list.Items.AddRange(this.underlyingToListItems());
}
...
public ListViewItem[] underlyingToListItems()
{
ListViewItem[] res = new ListViewItem[Underlying.Keys.Count];
int i = 0;
foreach (string ric in Underlying.Keys)
{
res[i] = new ListViewItem(new string[] { ric, Underlying[ric].ToString("MMM-dd hh:mm:ss") });
i++;
}
return res;
}
}
Я понимаю, что проблема в моем updateView (). В отладке код идет туда определенно. Полагая, что проблема должна была быть решена с помощью асинхронного «вызова», я ссылался на этот пост, который выглядел как ссылка: Переполнение стека: автоматизация вызова…
Тогда попробовал это:
private void updateView()
{
if (this.list.InvokeRequired)
{
this.list.Invoke(new MethodInvoker(() => { updateView(); }));
}
else
{
this.list.Items.Clear();
//this.list.Clear();
this.list.Items.AddRange(this.underlyingToListItems());
}
}
Он строит, но не имеет никакого эффекта. В режиме отладки никогда не идет в ветке 'if', всегда в 'else'.
Тогда это:
private void updateView()
{
this.list.Invoke((MethodInvoker)delegate
{
this.list.Items.Clear();
//this.list.Clear();
this.list.Items.AddRange(this.underlyingToListItems());
});
}
Я получаю «InvalidOperationException: Invoke или BeginInvoke не могут быть вызваны для элемента управления, пока не будет создан дескриптор окна».
Что такое очевидное, чего мне здесь не хватает? Или моя проблема на самом деле не та, о которой я думаю?
Спасибо, ребята!