Легкий инструментарий MVVM - RelayCommands, DelegateCommands и ObservableObjects - PullRequest
5 голосов
/ 04 января 2011

Я только начал экспериментировать с MVVM Light Toolkit Лорана Бюньона .Я думаю, что мне это действительно понравится, но у меня есть пара вопросов.

Прежде чем я доберусь до них, позвольте мне объяснить, откуда я.В настоящее время я использую комбинацию MVVM Foundation Джоша Смита и другой проект Codeplex под названием MVVM Toolkit .Я использую ObservableObject и Messenger из MVVM Foundation и DelegateCommand и CommandReference из MVVM Toolkit.

Единственное реальное совпадение между MVVM Foundation и MVVM Tookit состоит в том, что они оба имеют реализацию для ICommand: MVVM Foundation имеет RelayCommand, а MVVM Tookit имеет DelegateCommand.Из этих двух DelegateCommand представляется более сложным.Он использует CommandManagerHelper, который использует слабые ссылки, чтобы избежать утечек памяти.

С учетом сказанного, вот мои вопросы:

  1. Почему MVVM Light использует RelayCommandа не DelegateCommand?Является ли использование слабых ссылок в ICommand ненужным или не рекомендуется по какой-то причине?

  2. Почему в MVVM Light нет ObservableObject?ObservableObject - это просто часть ViewModelBase, которая реализует INotifyPropertyChanged, но очень удобно иметь отдельный класс, потому что view-модели - не единственные объекты, которые должны реализовывать INotifyPropertyChanged.Например, допустим, у вас есть DataGrid, который связывается со списком Person объектов.Если какое-либо из свойств в Person может измениться, когда пользователь просматривает DataGrid, Person потребуется реализовать INotifyPropertyChanged.(Я понимаю, что если Person автоматически генерируется с использованием чего-то вроде LinqToSql, он, вероятно, уже реализует INotifyPropertyChanged, но есть случаи, когда мне нужно создавать версии объектов-модели объектов для конкретного вида, скажем, потому что мне нужновключите команду для поддержки столбца кнопки в DataGrid.)

Спасибо.

PS Вот код для DelegateCommand из набора инструментов MVVM:

https://docs.google.com/document/pub?id=1ApCx5SbCfHi5fBhv8Ki3zA6j34sp2t80LQZdj89v8cU

Ответы [ 3 ]

4 голосов
/ 05 марта 2011

Похоже, что проблема, возникшая в связи с первым вопросом, была решена в последней сборке:

Согласно Сайт Codeplex MVVM Light Toolkit (в разделе «Ручное создание события CanExecuteChanged»)), CommandManager был полностью исключен.

Что касается Observable Object, я добавил элемент в систему отслеживания проблем на сайте Codeplex.

0 голосов
/ 04 января 2011

Вы также можете рассмотреть Catel . Он поддерживает DataObject (как универсальный, так и не универсальный), который поддерживает именно то, что вы ищете (объект, реализующий INotifyPropertyChanged, IDataErrorInfo и многое другое). Затем ViewModelBase является производным от очень мощного класса DataObjectBase, поэтому вы можете использовать DataObjectBase для объектов данных и ViewModelBase для моделей представлений.

Это также избавляет вас от создания мессенджеров, поскольку вы можете просто использовать атрибут InterestedIn в модели представления для получения уведомлений об изменениях другой модели представления.

0 голосов
/ 04 января 2011

Оба ваших вопроса настоятельно рекомендуют мне использовать для определения бизнес-логики что-то на больше , чем концепция View Model.

DelegateCommand определяет отдельный класс отдельно от модели представления. ObservableObject является экземпляром отдельного класса, кроме модели представления. Это не правило, а личное предпочтение на данный момент: модель представления мне достаточно как контейнер для бизнес-логики, относящейся к визуальным элементам. Это может предать мое предпочтение MVVM Light - которого мне не хватает на данный момент.

Я не совсем уверен в том, что происходит в примере с DataGrid. Что я могу сказать, так это то, что DataGrid не очень гибок - однако в WPF DataGridTemplateColumn может декларативно связывать модель представления с представлением (например, пользовательским элементом управления). Так что, возможно, это имеет смысл:

<DataGridTemplateColumn.CellTemplate>
    <DataTemplate DataView="{x:Type m:YourViewModelForButton}">
        <v:YourViewWithButton/>
    </DataTemplate>
</DataGridTemplateColumn.CellTemplate>
...