Я хочу создать Grid
элемент на другом потоке (создавая всю сетку дорого) и обновлять StackPanel
через Dispatcher
. Но вызов Dispatcher
всегда бросает InvalidOperationException
, независимо от того, что я делаю.Dispatcher.Invoke() с параметром всегда бросает InvalidOperationException
Вот мой код:
Grid grid = new Grid();
Dispatcher.Invoke(() => stackPanel.Children.Add(grid));
Что я пробовал:
Closing over a variable [не работает]
Grid grid = new Grid(); Grid closedOverGrid = grid; Dispatcher.Invoke(new Action(() => stackPanel.Children.Add(closedOverGrid)));
Using BeginInvoke [Didn не работает]
//declaring this in another thread. Grid grid = new Grid(); AddToPanel(grid); private void AddToPanel(Grid grid) { Dispatcher.BeginInvoke((Action)(() => { stackPanel.Children.Add(grid); })); }
Using a full declaration with DispatcherPriority [не работает]
Grid grid = new Grid(); System.Windows.Application.Current.Dispatcher.BeginInvoke( DispatcherPriority.Background, new Action(() => stackPanel.Children.Add(grid)));
Tried the .Freeze() method [не работает]
Grid grid = new Grid(); grid.Freeze(); // Not possible.
ли это на самом деле не представляется возможным, или я что-то упускаю? Спасибо за ваши ответы/комментарии.
Вы не должны создавать 'Grid' (и любой элемент пользовательского интерфейса) в потоке, отличном от UI, потому что, как только вы это сделаете, его нельзя использовать в потоке пользовательского интерфейса. Это стандартное поведение 'DispatcherObject' (обратите внимание, что текущий диспетчер запоминается внутри конструктора и никогда не изменяется). –