Должен ли я мутировать параметр, переданный методу Execute на ICommand? Если нет, то каким образом можно изменить состояние приложения или просмотреть модель после вызова команды?WPF Mutate Command Pattern
Мысли
Командное шаблон вызывает метод объекта, в случае WPF это модель или вид модели. Это требует, чтобы модель знала, как выполнять действие на себе. Мы все видели и использовали реализацию RelayCommand. Проблема, с которой я сталкиваюсь, заключается в том, что менять поведение по-разному сложно. Также трудно найти место для размещения кода «особого случая». Что делать, если я хочу показать другое представление?
Мне нравится идея создания команды для каждого случая использования. У меня будет конкретный класс, который реализует ICommand, который обрабатывает логику выполнения прецедента. Для этого требуется ссылка на модель, как и в Command Pattern. Разница в том, что логика действия будет за пределами модели и, таким образом, будет мутировать модель, прошедшую в качестве параметра. Давайте рассмотрим пример кода.
У меня есть окно со списком вездесущего объекта Person. Мы хотим вызвать команду на Person, которая очищает их имя. В MainViewModel есть коллекция объектов Person, называемых People.
<Window.Resources>
<commands:ClearNameCommand x:Key="ClearNameCommand"/>
</Window.Resources>
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
Это мой список, который привязан к коллекции и отображает каждого человека с кнопкой, чтобы очистить свое имя.
<ListBox ItemsSource="{Binding People}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Name" Width="100"/>
<TextBox Text="{Binding Name}" Width="100"/>
<Button Command="{StaticResource ClearNameCommand}" CommandParameter="{Binding}" Content="Clear"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Ниже приведен метод Execute на конкретном классе ClearNameCommand. Появится диалоговое окно с вопросом, хотите ли они выполнить действие. Я думаю, это доказывает, что это хороший пример того, почему вы не ставили эту команду в модель. Также представьте, что вам нужно было где-то регистрироваться, чтобы имя было очищено? Отменить Повторить, может быть? Куда ведет весь этот код? !!
public void Execute(object parameter)
{
Person p = parameter as Person;
if (p != null)
{
if (MessageBox.Show(
"Are you sure you want to clear the name?",
"Clear Name",
MessageBoxButton.YesNo,
MessageBoxImage.Question) == MessageBoxResult.Yes)
{
p.Name = "";
}
}
}
Я полагаю, что вы можете оставить весь код подготовки в команде, а затем вызвать метод Clear для Лица. Однако я все еще не убежден, что это лучший способ. Что делать, если явные изменения? Вы получаете Clear2 и Clear3 и так далее. Не говоря уже о методе для всех возможных вариантов использования или, возможно, даже больше.
Некоторых Подробнее Мысли
Так скажем, у меня есть вид модель с ссылкой на модель, которая позволяет Binding сквозных данных или оборачивают модель все вместе. Я хочу уйти от создания свойства Command в Model View для каждого отдельного варианта использования. Кроме того, что в этом плане так чисто? Вы по-прежнему мутируете объект Model в методе Execute. Я не думаю, что я так сильно изгибаю командный шаблон. Мое окно - это Клиент. Модель - это приемник. И кнопка - это Invoker. Единственное различие заключается в том, что вы вводите зависимость с invoker.
Чтобы перефразировать мой вопрос немного, кто-нибудь видит красные флаги для этого?
Я нашел это, исследуя шаблон команды. http://msdn.microsoft.com/en-us/library/cc984279.aspx
Спасибо за ответ. Я должен немного уточнить этот вопрос. Один из тех парней, которые создают View Model для каждой модели? –
Итак, просто для того, чтобы уточнить, вы не видели ничего плохого в том, чтобы мутировать модель в команде, была ли команда RelayCommand на ViewModel или конкретном классе? –
Спасибо, Шеридан. Я здесь не в левом поле. Я думаю, что это был законный вопрос. Обычно он недоволен изменением объекта, переданного в качестве параметра. Он не найден ни в одном шаблоне GoF. Даже шаблон команды. Свойство Command в WPF на самом деле не соответствует шаблону команды. Я определенно вижу значение использования команд в модели представления. Я использую их все время. Я просто думаю, что бывают случаи, когда мы создадим конкретный командный класс. Возможно, чтобы добавить функциональность во время выполнения. –