Проблема многопоточности привязки VisualState - PullRequest
0 голосов
/ 19 августа 2011

У меня есть приложение для записи звука в Windows Phone 7. Приложение позволяет пользователю воспроизводить записанные звуки.

Я стараюсь придерживаться рекомендаций MVVM, где это возможно.

У меня есть кнопка воспроизведения / остановки в списке всех записей. Каждая запись имеет свою собственную ViewModel, которая, кроме всего прочего, также управляет внешним видом соответствующей кнопки воспроизведения / остановки.

Кнопка имеет пользовательское визуальное состояние, определенное в ее стиле.

Визуальное состояние привязано к свойству ViewModel с помощью подхода, показанного здесь: http://tdanemar.wordpress.com/2009/11/15/using-the-visualstatemanager-with-the-model-view-viewmodel-pattern-in-wpf-or-silverlight/

Реализовав этот подход, всякий раз, когда я хочу изменить внешний вид кнопки воспроизведения / остановки, мне нужно установить свойство публичной строки (называемое «PlayStopVisualState») в моем ViewModel на «PlayingState» или «Normal», и это назначит соответствующее визуальное состояние моей кнопке.

Проблема в том, что когда пользователь нажимает кнопку воспроизведения, в фоновом потоке создается SoundEffectInstance, который воспроизводит звук. Затем поток ожидает окончания воспроизведения. Когда воспроизведение записи закончено (мне нужно отследить его в том же фоновом потоке или создать другое для простого отслеживания SoundEffectInstance.State), я возвращаю свойству PlayStopVisualState значение «Normal», но получаю исключение перекрестной ссылки. Разве MVVM не предназначен специально для того, чтобы позволить разработчикам манипулировать логическими переменными в модели представления и не беспокоиться о том, как их изменения отражаются в представлении?

Я знаю, что мне нужно выполнить настройку свойства PlayStopVisualState в потоке Dispatcher, чтобы проблема исчезла, но это просто неправильно. Это, с моей точки зрения, наносит ущерб всей цели MVVM, оставляя только организационное преимущество.

Или я что-то не так делаю? Благодаря.

UPDATE: Я обошел проблему с помощью

Deployment.Current.Dispatcher

но мне кажется, что это очень "некрасивое" решение, учитывая, что я почти во всем следую паттерну MVVM.

1 Ответ

1 голос
/ 05 сентября 2011

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

То, что вы забыли, это то, что ваша ViewModel создана в потоке пользовательского интерфейса.Таким образом, любое изменение ViewModel из фонового потока может быть операцией с несколькими потоками.

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

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