2015-01-12 4 views
2

Наш пользовательский интерфейс в настоящее время имеет множество элементов управления, которые связаны командами с некоторым комплексом CanExecutes. Проблема, с которой мы сталкиваемся, заключается в том, что всякий раз, когда CommandManager определяет, что пользовательский интерфейс должен быть повторно опротестован, все команды запускают свой CanExecute, что, в свою очередь, приводит к довольно сильному удару по конкретным сценариям.Как запретить CommandManager вызывать CanExecute всякий раз, когда есть взаимодействие с пользовательским интерфейсом?

Читая этот пост: How does CommandManager.RequerySuggested work?

Похоже, что CommandManager будет повторно evaulate на простом ключе вниз, события перемещения мыши и т.д. Есть ли способ, чтобы предотвратить это, и вместо этого, есть менеджер команды переоценивать при ручном вызове?

+2

Я не думаю, что вы можете. 'CanExecute' не должен содержать каких-либо сложных функций. Может быть, вы можете создать переменную bool, которая сообщит вам, может ли она быть выполнена или нет, и изменить эту переменную при изменении условий? – vesan

+0

И когда/где вы его вызываете? – Dzyann

+0

@ Dzyann, хорошим сценарием было бы, когда конкретное событие будет завершено (или будет поднято), а затем все переопределенные команды « –

ответ

1

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

public class RelayCommand : ICommand 
{ 
    public event EventHandler CanExecuteChanged; 

    // Further ICommand implementation omitted... 

    public void Invalidate() 
    { 
     var handler = this.CanExecuteChanged; 
     if (handler != null) 
     { 
      handler(this, EventArgs.Empty); 
     } 
    } 
} 

Вы затем вызвать его в вашем ViewModel переоценивать команду:

fooCommand.Invalidate(); 

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

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

Выработать на комментарии, большинство RelayCommand «s реализовать CanExecuteChanged событие так:

public event EventHandler CanExecuteChanged 
{ 
    add { CommandManager.RequerySuggested += value; } 
    remove { CommandManager.RequerySuggested -= value; } 
} 

Когда интерфейс поддерживает CanExecuteChanged событию командования он фактически косвенно подписался на CommandManager.RequerySuggested событие, поэтому ваш метод CanExecute вызывается каждый раз, когда предлагает повторный запрос.

Проще RelayCommand Я предложил избежать этой проблемы, не подписавшись на событие CommandManager.RequerySuggested.

+0

Бен, я вижу, как это обеспечит механизм для ручного вызова, но я не понимаю, как это предотвращает запуск CommandManager автоматически на основе взаимодействия с пользовательским интерфейсом. –

+0

Он не остановит 'CommandManager', но это не имеет значения. Упрощенный 'RelayCommand' не передает никаких зарегистрированных обработчиков событий через' CommandManager', то есть пользовательский интерфейс не будет переоценивать команду каждый раз, когда запускается событие RequerySposed. –

+0

Бен, это обеспечило механизм для моей проблемы. благодаря! –