Добавление стековых панелей к стековым панелям из другого потока (с отправкой?)
Я уже нашел несколько тем о многопоточности в wpf и получил большинство вещей для работы с диспетчеризацией, но есть одна вещь, которую я еще не понял. У меня есть стекпанель под названием "stackpanel1", к которой я добавляю стекпанели (в другом потоке) под названием "stackrow" как дочерние. (Еогеасп-петля)
stackPanel1.Dispatcher.Invoke(new Action(() => stackPanel1.Children.Add(stackrow)));
это похоже на этот вопрос: WPF C# - редактирование списка из другого потока
за исключением того, что мой "новый элемент" - это элемент пользовательского интерфейса (stackrow), и я получаю следующую ошибку: InvalidOperationException не обработано. Вызывающий поток не может получить доступ к этому объекту, потому что другой поток владеет им.
Как мне отправить "stackrow" в этой строке?
редактировать: стек создается в foreachloop
mainthread (создает новую тему) Thread t = new Thread(()=> addtackrows()); t.SetApartmentState(ApartmentState.STA); t.Start();
метод addtackrows ()
private void addstackrows()
{
Dispatcher stackpaneldispatcher = stackPanel1.Dispatcher;
stackPanel1.Dispatcher.Invoke(new Action(() =>
stackPanel1.Children.Clear()));
stackPanel1.Dispatcher.Invoke(new Action(() =>
stackPanel1.Orientation = Orientation.Vertical));
foreach (var randomelement in elementcollection)
{
StackPanel stackrow = new StackPanel();
Dispatcher stackrowdp = stackrow.Dispatcher;
stackrow.Dispatcher.Invoke(new Action(() =>
stackrow.Orientation = Orientation.Horizontal));
stackPanel1.Dispatcher.Invoke(new Action(() =>
stackPanel1.Children.Add(stackrow)));
}
}
1 ответ
Вы должны создать все ваши объекты пользовательского интерфейса в одном потоке:
private void addstackrows()
{
Dispatcher stackpaneldispatcher = stackPanel1.Dispatcher;
stackPanel1.Dispatcher.Invoke(new Action(() =>
{
stackPanel1.Children.Clear();
stackPanel1.Orientation = Orientation.Vertical;
}));
foreach (var randomelement in elementcollection)
{
stackPanel1.Dispatcher.Invoke(new Action(() =>
{
StackPanel stackrow = new StackPanel();
stackrow.Orientation = Orientation.Horizontal;
stackPanel1.Children.Add(stackrow);
}));
}
}
Кроме того, я бы сгруппировал все ваши Dispatcher
звонки. Каждый раз, когда вы звоните Invoke
производительность снижается. Итак, если вы не выполняете длительную операцию внутри цикла, вероятно, было бы лучше поместить всю функцию внутри Invoke
,