Обновление элементов пользовательского интерфейса из командного действия - PullRequest
0 голосов
/ 18 января 2019

Если я обновляю элемент пользовательского интерфейса несколько раз в командном действии, отображается только последнее изменение.Насколько я понимаю, это связано с тем фактом, что командные действия не выполняются в потоке пользовательского интерфейса, но я не понимаю, как правильно дать команду потоку пользовательского интерфейса для обновления элемента управления в то время, когда я хочу его обновить.

Это ситуация:

A TextBlock и Button привязаны к значениям в файле code-behind (это только для целей тестирования, я использую MVVM в производстве):

<TextBlock Text="{Binding Text}" />
<Button Content="Test"
        Command="{Binding Command}" />

Command - это простое RelayCommand, выполняющее следующее действие:

private void ChangeText()
{
    Text = "Text 1";

    Thread.Sleep(1000);

    Text = "Text 2";

    Thread.Sleep(1000);

    Text = "Text 3";
}

Программа просто спит в течение заданных двух секунд и отображает Текст 3 в текстовом поле первые два изменения пользовательского интерфейса игнорируются.Я хочу, чтобы он сначала отобразил Текст 1 , спит секунду, отобразит Текст 2 , снова спит секунду, а затем, наконец, отобразит Текст 3 .

Я думаю, что есть очень простой способ добиться этого, но я не нашел подходящего ответа здесь или где-либо еще.

1 Ответ

0 голосов
/ 18 января 2019

Напротив, командные действия выполняются в потоке пользовательского интерфейса, если не перемещено иначе, и это ваша проблема.

Thread.Sleep блокирует поток пользовательского интерфейса, поэтому он не может ничего сделать для отображения обновлений. Вместо этого используйте Task.Delay, чтобы выполнение метода больше не блокировало поток пользовательского интерфейса (это также препятствует тому, чтобы приложение выглядело "замороженным"):

private async void ChangeText()
{
    Text = "Text 1";
    await Task.Delay(1000);
    Text = "Text 2";
    await Task.Delay(1000);
    Text = "Text 3";
}
...