Хорошо, после вчерашнего дня я добавил новый уровень сложности. У нас все еще есть теоретический класс Model, ViewModel и View. На этот раз моя модель имеет Threading.Timer (Chosen специально, чтобы получить обратные вызовы таймера на «неправильной» нити.INotifyPropertyChanged, ObservableCollection, Threads и MVVM
Модель имеет ObservableCollection. Таймер обратного вызова добавляет элементы в коллекции.
ViewModel просто передает сбор в View, который содержит ListBox привязан к коллекции.
Это не работает.
модель также предоставляет строку, которая обновляется в том же обратном вызове таймера.
Это тоже отображается через viewmodel и привязывается к TextBox.
Это действительно работает.
Я видел подсказки в моем поиске в Google, что обновление коллекций не делает работу INotifyCollectionChanged, как ожидалось. Я получаю полную имплозию, даже не исключение, только немедленное прекращение действия приложения.
Итак, есть два вопроса:
Один относится к нашей дискуссии вчера. Я использую INotifyPropertyChanged и ObservableCollections в своей модели, потому что это то, на что работает представление. Мне все же имеет смысл использовать эти механизмы для уведомления моей модели просмотра или того, что когда-либо изменила базовая модель. Итак, как мне обрабатывать обновления, происходящие в другом потоке?
Во-вторых, что происходит, когда INotifyPropertyChanged работает со связыванием? Я привязываю свойство string к DependencyProperty, называемому Text, так же как и система DependencyProperty, которая возвращает мои изменения обратно в поток пользовательского интерфейса? Edit: И я могу полагаться на это, то есть делает это, потому что они ожидают, что я буду говорить с ним поперечным потоком, или это просто уловка, на которую я не должен полагаться?
ListBox связан через ItemsSource = "{Binding ObsCollection}". Когда это приведет к сбою приложения. На самом деле, я сначала начал таймер, когда была создана модель, которая произошла, когда DataContext окна был установлен, так что это будет на самом деле бомбой Visual Studio ...
Благодаря
Это круто, но что такое «правильный» процесс для решения этой проблемы с точки зрения MVVM? Таким образом, поток моей модели обновляет коллекцию. Должна ли моя модель узнать о диспетчерах? Это кажется неправильным. Это говорит о том, что мой ViewModel более тяжелый, чтобы справиться с правильным разделением между Model и View. Имеет ли это смысл? – Ian
Не существует «правильного» подхода. Тем не менее, мое личное предпочтение заключается в создании простого интерфейса, от которого зависит ViewModel, IMarshalledInvoker, который имеет единственный метод для вызова некоторых действий над каким-либо другим потоком. Когда я соединяю ViewModel с представлением, я создаю IMarshalledInvoker, который использует диспетчер под обложками. С этим шаблоном я все еще могу тестировать блок, у меня все еще есть поддержка дизайнера, т. Е. Это хорошая MVVM ;-) – ColinE
А теперь все вместе. В сущности, существуют разрозненные знания, которые связаны друг с другом так, как я не рассматривал. Первая biggie, мы знаем, что сборка потокобезопасной коллекции сложна. Я забыл об этом и не сделал ассоциации в моей голове ... По существу, я добавляю только один поток. Забавно, как вы забываете, почему вы делаете что-то. Так что я думаю, что суть ответа заключается в том, чтобы вносить изменения из нескольких потоков в один поток. Итак, есть один канал между представлением и viewmodel ?? – Ian