C # / WPF Связывание с данными и фоновые рабочие - PullRequest
1 голос
/ 16 августа 2011

Update2

Я переписал весь вопрос, потому что некоторые вещи стали намного понятнее, теперь проблема заключается в том, что я создал список свойств DependencyProperties в другом потоке, отличном от того, где будут использоваться свойства DependencyProperties: (.

Когда я работаю над BackgroundWorker, привязки XAML вызывают ArgumentException

Необходимо создать DependencySource в том же потоке, что и объект DependencyObject.

У меня есть следующие настройки:

У меня есть простой класс, который реализует INotifyPropertyChanged, который содержит несколько целых, списков и словарей.

public class Calculator : INotifyPropertyChanged
{
    //Note that InstanceGroup is a dependency object
    private List<InstanceGroup> instanceGroups = new List<InstanceGroup>();
    public List<InstanceGroup> InstanceGroups
    {
        get { return instanceGroups; }
        set { instanceGroups = value; }
    }

    // snip //

    public void Calculate()
    {
        InstanceGroups = MyNewFilledInstanceGroup;
            if (PropertyChanged != null)
            {
              PropertyChanged(this, new PropertyChangedEventArgs("instanceGroups"));
            }
    }
}

В UserControl я использую BackgroundWorker для запуска метода Calculate, потому что это может занять много времени:

BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += delegate(object o, DoWorkEventArgs args)
{
    lock (Calculator)
    {       
        Calculator.Calculate();
    }
};
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
worker.RunWorkerAsync();

В файле XAML UserControl у меня есть несколько привязок к Calculator, например {Binding Path=Calculator.InstanceGroups, Path=userControlName}.

(Общая цель - выполнить всю работу в методе Calculate в отдельном потоке, чтобы я мог показать индикатор выполнения или что-то в этом роде)

Ответы [ 4 ]

2 голосов
/ 16 августа 2011

Я не уверен, что вам нужно использовать DP для этой коллекции Observable.Лучше всего хранить его во ViewModel.

ObservableCollections не являются поточно-ориентированными, и вам необходимо использовать Dispatcher для обновления коллекции.

Google было несколько постов с расширением до ObservableCollection, в которых использовался Dispatcher.

Эта ссылка может помочь

1 голос
/ 16 августа 2011

Любой DependencyObject включает свойство Dispatcher, которое может помочь вам перенести работу в правильный поток для этого объекта.

Вы можете использовать Dispatcher.Invoke или Dispatcher.BeginInvoke для запуска кода в правильном потоке.

0 голосов
/ 23 августа 2013

Для полноты картины я бы упомянул два решения гуру WPF Дин Мел :

  1. Создайте потокобезопасную наблюдаемую коллекцию.Это решение старой школы, которое просто работает.Чтобы получить исходный код, прочитайте короткую статью в своем блоге .Об этом Анварбек Раупов упоминал ранее в этой теме.Аналогичное решение есть в блоге Саши Барбера .
  2. Использование библиотеки Reactive Extensions .См. эту статью для примера.Это немного громоздко для одной задачи, но в то же время она приносит множество современных инструментов, которые пригодятся.
0 голосов
/ 16 августа 2011

Единственное решение, по-видимому, заключается в том, чтобы не создавать DependencyProperties ( Как обрабатывать ObservableCollection <> результат параллельной задачи в MVVM? ) в фоновой задаче, это странное поведение стоило мне лучшей частидень.Но, по крайней мере, теперь я знаю, в чем проблема.

...