Привязка команд MVVM - PullRequest
       12

Привязка команд MVVM

5 голосов
/ 05 декабря 2009

Я пытаюсь выучить шаблон MVVM. Основная проблема, с которой я сталкиваюсь, - это узнать, где я должен декларировать, создавать и связывать объекты команд.

2 примера:

  1. У меня есть основная форма, которая действует как доска переключателей или главное меню. Кнопка Selct 1 и вид 1 отображаются, кнопка выбора 2 и вид 2 отображаются. Отлично. Теперь я хочу вернуться к основной форме, поэтому мне нужна кнопка в представлении 1 (и представлении 2), которая называется «Главное меню». Где я должен определить команду и обработчики команд, чтобы я мог связываться с командой «ShowMainMenu»? Я мог бы создать их в View2ViewModel, но тогда у меня нет доступа, чтобы показать основной вид? Или я мог бы создать thim в модели MainView, но затем Как связать их с ними в модели дочернего представления (я использую объект RelayCommand в соответствии с рекомендацией mvvm, и они не всплывают до родителя.)

  2. У меня есть два пользовательских элемента управления, видимых в одном представлении главного окна, назовем их MainView, UC1 и UC2. каждый из них имеет ViewModel MainViewModel, UC1ViewModel, UC2View Model. У меня есть кнопка на UC1 под названием «AddItem». Следует добавить элемент в список на UC2. Каков правильный способ установить AddItemCommand и привязать к нему. Должна ли команда быть в MainViewModel, Uc1ViewModel или UC2ViewModel? И как бы я ни привязался к нему.

Спасибо за вашу помощь.

Ответы [ 2 ]

3 голосов
/ 05 декабря 2009

1) Вы можете наследовать View1Model и View2Model от одной базовой ViewModel и определять там ShowMainMenu.

или (это мой подход)

Создайте RootView с ContentPresenter, который покажет все ваши представления. Создайте RootVeiwModel со свойством ViewContent. Привязать свойство содержимого ContetnPresenter к свойству ViewContent объекта RootViewModel. Вы можете использовать object в качестве типа ViewContent, но я советую вам определить интерфейс, который поддерживается MainVView1Model, View1Model и View2Model. Изменение ViewContent должно вызвать ProprtyChangedEvent. Определите ShowMainViewCommand в RootViewModel, который просто изменит ViewContent на MainViewModel (и он будет отображаться как MainView). Затем свяжите свойство Command для Button в View1 и View2 с этой командой, например, следующим образом:

{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type RootView}}, 
                         Path=DataContext.ShowMainViwe}

Есть некоторый код, объясняющий, что я пытаюсь сказать:

RootView.xaml

...
<ContentPresenter Content={Binding ViewContent} />
...

RootViewModel.ca

class RootViewModel : INotifyPropertyCahnged
{
    ...
    private object _ViewContent;
    public object ViewContent
    {
        get {return _ViewContent;}
        set
        {
            _ViewContent = value;
            if (PropertyChanged != null)
            {
                PropertyChanged ("ViewContent");
            }

        }
    }

    private RelayCommand _ShowMainView;
    public ICommand ShowMainView
    {
        get 
        {
            if (_ShowMainView == null)
            {
                _ShowMainView = new RelayCommand(x => ViewContent = new MainViewModel());
            }
            return _ShowMainView;
        }
    }
    ...
}

2) Добавить ссылку на MainViewModel в UC1ViewModel и UC2ViewModel - так можно влиять на другие элементы управления. MainViwModel должен содержать свойства, содержащие UC1ViewModel и UC2ViewModel. Элементы второго пользовательского элемента управления должны содержаться в ObservableCollection.

Я просто покажу вам, как это работает по коду:

class UC1ViewModel : INotifyPropertyChanged
{
    ...
    private MainViewModel _Parent;
    public UC1ViewModel(MainViewModel parent)
    {
        _Panert = parent;
    }

    private RelayCommand _AddItemToUC2;
    public ICommand AddItemToUC2
    {
        get
        {
            if (_AddItemToUC2 = null)
            {
                // UC2Content is UC2ViewModel
                // Items is ObservableCollection
               _AddItemToUC2 = new RelayCommand(x => _Parent.UC2Content.Items.Add(...));
            }
            return AddItemToUC2;
        }
    }
    ...
}
2 голосов
/ 05 декабря 2009

MainModel может иметь свойство для каждой UCxViewModel или, проще, список ViewModel. Команда «Показать» создаст соответствующий UVxViewModel, подпишется на событие «OnClose», опубликованное UVxViewModel, и добавит его в список. MainView имеет элемент управления (например, Tab Control), связанный с этим списком, и шаблоны данных, определяющие представления, которые будут использоваться для каждого UCxViewModel. Когда UVxViewModel запускает событие OnClose, MainModel удаляет его из списка, в результате чего соответствующее представление закрывается.

Для части «Добавить элемент» ViewModels должен совместно использовать один и тот же список элементов (модель). UC2ViewModel может затем добавить элемент, и UC1View будет обновлен (при условии, что список реализует INotifyCollectionChanged).

Я нашел это объяснение очень полезно для понимания MVVM.

...