2016-01-20 5 views
2

Я работаю над проектом в WPF-MVVM, где у меня есть основное окно, содержащее элемент управления Tab с двумя вкладками. На каждом из этих вкладок есть кнопка.WPF MVVM - Правильный способ вызова метода в «родительском» View Model

В этом проекте представлены 3 разных вида моделей: один для главного окна и по одному для каждой вкладки. Когда одна из кнопок нажата, мне бы хотелось, чтобы модель «родительского» представления (Модель просмотра для главного окна) выполняла некоторые действия, такие как закрытие приложения.

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

Screenshot of Application

Code on Pastebin

Примечания: Я не использую какое-либо рамки, такие как MVVM Light или Prism.

+0

взглянуть на Команды http://www.wpf-tutorial.com/commands/introduction/ – komaflash

+0

@komaflash Да, Я знаком с привязкой к Commands в представлении, я просто не думал использовать их в контексте ViewModel -> Связь ViewModel. Похоже, что он мог бы работать достаточно хорошо, чтобы взять команду (CloseCommand и т. Д.) Или что-то еще в качестве аргумента конструктора, а затем просто вызвать эту команду всякий раз, когда это необходимо. – Everix

+0

Вы используете относительную привязку, взгляните на мой ответ. – komaflash

ответ

0

Я не уверен, о правильном пути, но здесь два варианта, которые приходят на ум, и кажется довольно правильными для меня :)

Один добавить MainWindowViewModel Parent {get;set;} свойства детской модели, а затем в главном MainWindowViewModel, чтобы установить это свойство всякий раз, когда вы добавляете или удаляете дочерний элемент в коллекцию Tabs (так как это ObservableCollection, вы можете добавить к ней обработчики событий, чтобы убедиться, что установить свойство Parent независимо от того, как дочерний элемент добавляется в коллекцию). Что-то вроде этого используется в Win Forms для поддержания отношений между родителями и дочерними элементами между окнами и элементами управления.

Во-вторых, для добавления события в дочерний объект ViewModel и для подписки/отмены подписки на это событие в родительском представлении ViewModel при добавлении/удалении дочернего элемента (аналогично первому варианту только с событиями, а не с собственностью). Затем из обработчика событий вы можете позвонить по методу, который вам нужен

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

Что более правильно, зависит от вашей потребности в текущем проекте.

+0

Да, я думал об использовании первого метода. Тем не менее, я думаю, что делать именно то, что соединяет две модели просмотра вместе слишком сильно и не позволяет вам хорошо тестировать блок, поскольку вы не можете макетировать «родительскую» модель представления. Второй способ кажется жизнеспособным, но он ошибочно справляется с этим в случае, основанном на событиях, из-за характера отношений между моделями представлений. – Everix

+0

Определенно второй, родитель должен всегда вводить свои зависимости в дочерний элемент. Это особенно важно, когда речь идет о модульном тестировании. –

1

Вы можете получить доступ к родителям DataContext с помощью относительно связывания, как это:

Binding="{Binding RelativeSource={RelativeSource FindAncestor, 
    AncestorType={x:Type Window}}, Path=DataContext.AllowItemCommand}" 
Смежные вопросы