Настройка команд WPF из нескольких моделей представления

Как и в любом приложении MVVM WPF, у меня есть несколько моделей представления. У каждого есть несколько команд. В моем представлении реализован пользовательский интерфейс Fluent (лента Office), поэтому некоторые элементы подсвечиваются в зависимости от контекста приложения. Лента является дочерней по отношению к основному приложению.

Базовая структура моего приложения заключается в том, что оно управляет КУРСОМ. В КУРСЕ есть несколько МОДУЛЕЙ, поэтому у меня есть виртуальная машина для курса и модуля... и у каждого есть команды.

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

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

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

Я думал о маршрутизируемых командах/событиях, но кто-то сказал мне, что это не сработает, потому что они не будут всплывать до самого окна и обратно до ленты.

Ищу здесь какое-то руководство... Я немного новичок в MVVM (но мне это нравится!).


person Andrew Connell    schedule 06.05.2010    source источник


Ответы (1)


Идея: представить класс ShellCommands, который предоставляется как служба.

public class ShellCommands : IShellCommands
{
    public ICommand SaveCommand { get; set; }
    ...
}

Затем CourseViewModel и ModuleViewModel могут использовать одну и ту же службу для регистрации своих команд.

public class CourseViewModel : ViewModel 
{
    public CourseViewModel(IShellCommands shellCommands, ...)
    {
        this.ShellCommands = shellCommands;
        ...
    }

    public IShellCommands ShellCommands { get; private set; }
}

В XAML вы можете получить доступ к службе через свойство ShellCommands.

<MenuItem Header="Save" Command="{Binding ShellCommands.SaveCommand}"/>

.

Дополнительная информация: Структура приложений WPF (WAF)

person jbe    schedule 07.05.2010
comment
Интересная идея... пытаюсь реализовать, чтобы посмотреть, как это будет работать. Я создал класс объектов ShellCommands и общедоступное свойство в моем классе MainWindow (поскольку при загрузке приложения оно создает экземпляр CourseViewModel и привязывает его к DataContext. Затем я передал свойство ShellCommands в CourseViewModel. Однако, когда я привязываю его на кнопку, команда не срабатывает.После установки точки останова после создания CourseViewModel я вижу, что команда была подключена, но она просто не срабатывает... та же команда срабатывает без этого метода (поэтому CanExecute работает) Идеи? - person Andrew Connell; 08.05.2010
comment
Сотрите последний комментарий... Я подключил его для одной команды в CourseViewModel. Однако ниже по течению я создаю экземпляры ModuleViewModel, у которых есть свои собственные команды. Проблема в том, что свойство ShellCommand в главном окне не обновляется этими новыми командами, поскольку они являются новыми экземплярами ModuleViewModel. Похоже, это будет проблемой, с которой люди будут часто сталкиваться. Нет ли общепринятой методики для решения этой проблемы (или я просто делаю это неправильно)? - person Andrew Connell; 08.05.2010
comment
Когда я правильно понимаю ваш комментарий, вам просто нужно реализовать интерфейс INotifyPropertyChanged в ShellCommands. Когда ModuleViewModel устанавливает команду, объект ShellCommands вызывает событие PropertyChanged и уведомляет WPF о необходимости обновить привязку команды в главном окне. - person jbe; 09.05.2010