2016-03-09 3 views
0

Я столкнулся с дилеммой в использовании параметра CanExecute в CommandBinding для меню в моем приложении.WPF CanExecute в зависимости от того, что один фактор

Ситуация следующая: само приложение может работать в определенных режимах, например. режим работы, режим просмотра и т. д. В зависимости от режима некоторые элементы меню должны быть включены или нет (следовательно, их можно выполнить или нет).

Что я сделал до сих пор является создание 4 обработчиков событий для CanExecute:

private void Mode1CanExecute(object sender, CanExecuteRoutedEventArgs e); 
private void Mode1CannotExecute(object sender, CanExecuteRoutedEventArgs e); 
private void Mode2CanExecute(object sender, CanExecuteRoutedEventArgs e); 
private void Mode2CannotExecute(object sender, CanExecuteRoutedEventArgs e); 

как некоторые команды меню являются общими для обоих режимов, некоторые являются исключительными для каждого режима.

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

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

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

Мой вопрос: Какова была бы лучшая практика в этом случае, так что логика приложения (доступность выполнения команд) гарантирована, а также читаемость кода остается на разумном уровне?

Благодарим за любые предложения.

ответ

1

Ну, что я делаю - это у меня всегда есть 1 canexecute метод за команду Таким образом, это простой и последовательный и Вы знаете, где искать проблему

Другая точка иметь его в 1 метод - это просто чистая проверяемость и читаемость.

Очень просто, чтобы проверить то

public bool CanExecuteGoCommand(){ 
if (xxx) 
    return true; 
else 
    return false; 
} 

и метод может быть столь же большой, как Вы хотите, с так много Если, как вы должны с миллионом условия, режимы, переменные ЭСТ ..

+0

Спасибо. Я согласен с вами в том, что он прост и последователен, если вы начали с такого подхода. Нашей отправной точкой было меню с чем-то вроде 50 'MenuItem's, где некоторые были применимы к одному из режимов программного обеспечения. Таким образом, создаем один обработчик события «CanExecute» и применяем его к применимым «MenuItem's». Я считаю, что настало время для рефакторинга приложения. – Mike

+1

У меня была аналогичная проблема с «режимами приложений». В конце дня - это всего лишь одна статическая переменная, доступная для всего приложения. то вы можете использовать его в любом месте .. в любом случае canExecute. Таким образом, все, что вам нужно, - это 1 событие, appMode изменено - и простой обработчик событий в вашей виртуальной машине - onAppModeChaged + =() => {RaisePropChaged ("appMode");} – Marty

0

Что Я бы сделал это, используя реализацию DelegateCommand или RelayCommand в качестве вашего свойства ICommand в вашей ViewModel. Любой из них позволит вам передать Func в конструктор экземпляра ICommand в качестве делегата CanExecute. Когда вы передаете этот Func, вы можете включить другие свойства вашего ViewModel в качестве закрытий и, следовательно, получить доступ к ним в делегате. Это позволит вам объединить параметр CanExecute с любым другим членом в ViewModel.

+0

Спасибо, Дин. Я дам ему попробовать и поделиться результатами. – Mike