Считается ли плохой практикой, чтобы объекты ViewModel содержали Dispatcher? - PullRequest
6 голосов
/ 12 марта 2010

Мое приложение WPF структурировано с использованием шаблона MVVM. ViewModels будет асинхронно связываться с сервером, и когда запрашиваемые данные возвращаются, вызывается обратный вызов в ViewModel, и он что-то делает с этими данными. Это будет выполняться в потоке, который не является потоком пользовательского интерфейса. Иногда эти обратные вызовы включают работу, которую необходимо выполнить в потоке пользовательского интерфейса, поэтому мне нужен Dispatcher. Это могут быть такие вещи, как:

  • Добавление данных в коллекцию ObservableCollection
  • Триггерные команды Prism, которые будут настраивать отображение в графическом интерфейсе
  • Создание объектов WPF некоторого вида.

Я стараюсь избегать последнего, но два первых пункта здесь я считаю разумными для ViewModels. Так; Можно ли, чтобы ViewModels содержала Dispatcher, чтобы иметь возможность вызывать команды для потока пользовательского интерфейса? Или это считается плохой практикой? И почему?

Ответы [ 4 ]

3 голосов
/ 12 марта 2010

Поскольку ObservableCollection должен быть обновлен в потоке, к которому он принадлежит (при условии, что приложение с графическим интерфейсом), а ObservableCollections должен быть частью ViewModel, то для ViewModel есть явный случай наличия диспетчера.

Я не вижу, чтобы это было частью модели.

2 голосов
/ 12 марта 2010

В идеале ViewModel должно быть полностью независимым от используемой технологии пользовательского интерфейса. Теоретически мы должны быть в состоянии повторно использовать его для Windows Forms (если мы немного увеличим элементы управления Windows Forms для поддержки лучшей привязки) для веб-страниц (Я предполагаю какой-то причудливый механизм, который скомпилирует ViewModel также в Javascript ) и для любых будущих технологий. Не все эти технологии будут использовать модель Dispatcher.

Тем не менее, я считаю прагматичным компромиссом включить Dispatcher в ViewModel в наши дни. В моем базовом классе ViewModel я проверяю текущий Dispatcher:

    protected override void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (Deployment.Current.Dispatcher == null || Deployment.Current.Dispatcher.CheckAccess())
        {
            base.OnPropertyChanged(sender, e);
        }
        else
        {
            Deployment.Current.Dispatcher.BeginInvoke(() => base.OnPropertyChanged(sender, e));
        }
    }

У меня все еще есть зависимость от System.Windows, конечно, ну да ладно. : ->

1 голос
/ 12 марта 2010

Я согласен с kyoryu и хотел бы отметить, что он создает зависимость только от библиотеки ServiceModel (которая у вас уже есть), а не от самого View, поэтому очень мало возражений против этой конструкции.

Вчера я попробовал несколько вещей с WPF, простой виртуальной машиной и потоками и пришел к выводу, что мне абсолютно необходимо передать Dispatcher на виртуальную машину.

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

0 голосов
/ 07 июня 2013

Вам следует рассмотреть возможность использования AsyncOperation.

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