2013-11-13 7 views
0

Должен ли я мутировать параметр, переданный методу 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

ответ

0

Я действительно не знаю, о чем вы говорите ... у вас, похоже, очень ... эр, уникальный способ работы с Command.

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

Класс модели никогда не должен содержать Command s в нем ... вместо этого поместите их в ту модель, которая отображает этот класс модели.

... это трудно поменять поведение

Опять же ... что? Не «свопинг поведения». A Command не должен изменять свою функциональность. Просто создайте один для каждой функции.

Это также трудно найти место, чтобы положить, что «особый случай» код

Что такое «особый случай» код?

Что делать, если я хочу показать другой вид?

Каждый вид должен иметь свою собственную модель обзора. Каждая модель представления должна иметь свой собственный набор объектов ICommand. Это действительно не проблема, если вам нужно дублировать небольшое выражение Lambda в RelayCommand.

Представьте, что вам нужно было где-то регистрироваться, чтобы имя было очищено? Отменить Повторить, может быть? Куда ведет весь этот код? !!

Просмотреть модель, просмотреть модель, просмотреть модель.

Я полагаю, вы можете оставить весь код подготовки в команде, а затем вызвать четкий метод на Лице

Как вы думаете, разница будет между вызовом p.Name = "" и вызова p.ClearName() который сделал тоже самое? Никакой разницы, или, самое большее, это потребовало бы более дробного вызова метода, чем установка свойства напрямую.

Что делать, если четкие изменения? В итоге вы получаете Clear2 и Clear3 и т. Д.

Еще раз ... что ??? Как будет Name = "" изменить?

Хотя я надеюсь, что я ответил некоторые ваши вопросы, я думаю, что я обязательно не поняли вас в некотором роде, потому что я не полностью понимаю ваш вопрос. Пожалуйста, не стесняйтесь задавать дополнительные вопросы, но, пожалуйста, добавьте их как редактирование на свой вопрос, и я отвечу в этом ответе, чтобы комментарии не смеялись долго.


UPDATE >>>

В ответ на первые два комментария:

Да ... почти во всех случаях, я бы один вид на один вид модели. И нет, у меня нет абсолютно никакой проблемы с изменением значения ничего от Command. Я не могу придумать, почему вы думаете, что это не нормально. Представьте себе этот сценарий:

У вас есть список объектов и панель редактирования в пользовательском интерфейсе, которые пользователь может использовать для редактирования объектов. У вас также есть Button с Command, который называется Duplicate. Теперь, по определению, Command собирается «мутировать», как вы его называете, объект данных или класс модели.

Это создаст новый объект и задает его свойства в зависимости от значений текущего выбранного объекта. Вы предполагаете, что это Command как-то не так для этого? На мой взгляд, что подавляющее большинство функциональных возможностей (или методов) Command будет «мутировать» некоторое свойство или свойства объектов данных в представлении ... как еще мы предоставляем эту полезную функциональность?

И продолжить «где это должно быть?». вопрос ... где еще это может быть? В модели просмотра мы имеем доступ к выбранному в данный момент элементу и всему набору предметов. Из модели просмотра мы можем иметь доступ к любому числу сервисов, которые предоставляют нам все возможности. Вам будет трудно связаться с некоторыми из этих вещей из ваших отдельных классов Command.

+0

Спасибо за ответ. Я должен немного уточнить этот вопрос. Один из тех парней, которые создают View Model для каждой модели? –

+0

Итак, просто для того, чтобы уточнить, вы не видели ничего плохого в том, чтобы мутировать модель в команде, была ли команда RelayCommand на ViewModel или конкретном классе? –

+0

Спасибо, Шеридан. Я здесь не в левом поле. Я думаю, что это был законный вопрос. Обычно он недоволен изменением объекта, переданного в качестве параметра. Он не найден ни в одном шаблоне GoF. Даже шаблон команды. Свойство Command в WPF на самом деле не соответствует шаблону команды. Я определенно вижу значение использования команд в модели представления. Я использую их все время. Я просто думаю, что бывают случаи, когда мы создадим конкретный командный класс. Возможно, чтобы добавить функциональность во время выполнения. –

 Смежные вопросы

  • Нет связанных вопросов^_^