Потоки WPF: могу ли я обновить контекст данных элемента управления в потоке без пользовательского интерфейса? - PullRequest
6 голосов
/ 11 декабря 2010

Можем ли мы обновить контекст данных элемента управления WPF в потоке, не являющемся пользовательским интерфейсом?

Скажем, у нас есть Label с MyClass в качестве контекста данных и привязка Content к MyProperty:

<Label Name="label" Content="{Binding MyProperty}" />,

, где MyClass - это просто:

public class MyClass : INotifyPropertyChanged
{
    int _myField;
    public int MyProperty
    {
        get
        {
            return _myField;
        }
        set
        {
            _myField = value;
            PropertyChanged(this, new PropertyChangedEventArgs("MyProperty"));
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

В потоке без пользовательского интерфейса мы можем выполнить myClass.MyProperty = "updated", чтобы обновитьсодержимое ярлыка, но мы не можем сделать label.Content = "updated" напрямую.Это правильно?

Мой собственный ответ :

Вот что я нашел:

  • Из не-пользовательского потока вы не может обновить элемент управления;
  • из потока, не являющегося пользовательским интерфейсом, вы можете обновить свойства контекста данных элемента управления;
  • из не-В пользовательском интерфейсе вы не можете добавлять или удалять элементы из ObserverableCollection, который связан с элементом управления.Но есть обходной путь : http://geekswithblogs.net/NewThingsILearned/archive/2008/01/16/have-worker-thread-update-observablecollection-that-is-bound-to-a.aspx

1 Ответ

2 голосов
/ 11 декабря 2010

Да, это правильно. Также есть дополнительные предупреждения с коллекциями (событие CollectionChanged должно выполняться в потоке пользовательского интерфейса).

Обычно вы используете ObservableCollection<T> для привязки к коллекции. Если вы обновите эту коллекцию из потока, не являющегося пользовательским интерфейсом, код будет прерываться, поскольку события запускаются из того же потока, в котором они выполняются (ObservableCollection<T> запускает событие, когда происходят изменения в коллекции). Чтобы обойти это, вы должны предоставить делегат пользовательской реализации ObservableCollection<T>, которая запускает событие в потоке пользовательского интерфейса (с помощью Dispatcher).

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