Изменить значение пользовательского интерфейса из кода позади в задании \ поток - PullRequest
0 голосов
/ 25 мая 2018

В wpf Предположим, у меня есть метка счетчика, в коде позади я пытался увеличивать значение каждые 3 секунды, но это не работает, я имею в виду что-то вроде:

XAML:

<Label x:Name="MyLabel" Content="Label" />

Код:

public MyClass()
{
 Task t = Task.Factory.StartNew(() =>
        {
            int i = 1;
            while (true)
            {
                MyLabel.Content=i;
                Thread.Sleep(3000);
                i++;
            }
        });
}

Вывод: метка остается прежней

1 Ответ

0 голосов
/ 28 мая 2018

WPF UIElement может быть доступен только в одной теме.Таким образом, вы не можете получить доступ или изменить значение <Label/>.

. Но WPF также предоставляет модель потока с именем Dispatcher, вы можете получить Dispatcher элемента UIElement и вызвать ваше действие в исходном потоке..

Что вам нужно сделать, это изменить MyLabel.Content=i на MyLabel.Dispatcher.InvokeAsync(() => MyLabel.Content = i);.

Весь код:

Task.Run(async () =>
{
    int i = 1;
    while (true)
    {
        // Note: this works because the thread slept 3000ms.
        // If the thread doesn't sleep, we should declare a new variable
        // so that i will not change when the action invokes.
        // That means `var content = i;`
        // Then `MyLabel.Dispatcher.InvokeAsync(() => MyLabel.Content = content);`
        await MyLabel.Dispatcher.InvokeAsync(() => MyLabel.Content = i);
        await Task.Delay(3000);
        i++;
    }
});

Я изменяю ваш синхронизированный вызов на асинхронныйпозвоните, и это рекомендуется.


Вы обнаружите, что Dispatcher.InvokeAsync очень полезно, когда вы пытаетесь обновить пользовательский интерфейс в фоновом потоке.Кроме того, вы можете добавить параметр DispatcherPriority, чтобы определить приоритет выполнения всех вызванных вами действий.

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