Обработка команд всего приложения - PullRequest
2 голосов
/ 17 декабря 2010

Я изучаю WPF и MVVM, чтобы оценить, хотим ли мы реализовать это в проекте.

Есть одна особенность, которую я совершенно не могу понять (моя книга по WPF еще не поступила).

Я прочитал статью Джоша Смита «Приложения WPF с шаблоном проектирования Model-View-ViewModel», а также его статью «Использование RoutedCommands с ViewModel в WPF».

Мое демонстрационное приложение несколько отличается от демонстрации Джоша Смита тем, что у меня есть пункты меню, которые не связаны напрямую с моделью основного вида, а скорее будут обрабатываться другими моделями представления.

Мое главное окно привязано к объекту MainViewModel, который предоставляет объект под названием View (производный от класса ViewModelBase и привязанный к главному окну через ContentControl). Этот объект View заменяется другими ViewModel, такими как CustomerViewModel, CustomersViewModel и т. Д. (Они отображаются с использованием представлений, определенных в моем словаре ресурсов:).

Все это хорошо и найти, но, поскольку я не хочу, чтобы пункты меню в моем главном окне (такие как «Создать», «Сохранить» и т. Д.) Должны были быть включены, отключены на основе представления, которое я нашел в статье Джоша Смита о шаблоне CommandSink (?) но он утверждает, что он устарел, и лучше использовать RelayCommand.

Теперь я в замешательстве, так как не могу понять, как реализовать эту функцию с помощью этого подхода.

Спасибо, Винсент

1 Ответ

0 голосов
/ 17 декабря 2010

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

Затем заставьте ваше главное меню выглядеть примерно так:

<Menu>
   <MenuItem Header="File">
      <!-- content for your application's File menu goes here -->
   </MenuItem>
   <MenuItem Header="Edit">
      <!-- content for your application's Edit menu goes here -->
   </MenuItem>
   <MenuItem Header="{Binding SelectedView.MenuItem.Header}"
             ItemsSource={Binding SelectedView.MenuItem.Items}/>
   <MenuItem Header="Help">
      <!-- content for your application's Help menu goes here -->
   </MenuItem>
</Menu>

Редактировать

Я думаю, что я неправильно понял ваш вопрос, но отчасти это потому, что я думаю, что на ваш вопрос ответить гораздо легче, чем тот, который, как я думал, вы задавали.Создайте свойство RoutedCommand в вашей модели представления приложения с именем DisabledCommand, которое всегда отключено.Затем свяжите меню вашего приложения с такими командами:

public RoutedCommand SaveCustomerCommand
{
    get
    {
       CustomerView cv = SelectedView as CustomerView;
       return cv == null
          ? DisabledCommand;
          : ((CustomerViewModel)cv.DataContext).SaveCommand;
    }
}

Кастинг выглядит немного неловко, но в остальном это просто, даже элегантно.Единственная деталь реализации, которую ваше представление приложения должно знать о представлении клиента, - это то, что в его модели представления есть SaveCommand.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...