Как вызвать RaiseCanExecuteChanged для всех DelegateCommand и DelegateCommand <T>в базовом классе ViewModel - PullRequest
4 голосов
/ 23 февраля 2012

Я разрабатываю приложение WPF с использованием Prism и MVVM.

Одним из требований приложения является возможность входа в систему от имени другого пользователя (с разными разрешениями).

Теперь большинство разрешений просто разрешать или запрещать отображение определенного вида. Все они реализованы как DelegateCommand или иногда как DelegateCommand<T>

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

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

        Type myType = this.GetType();
        IList<PropertyInfo> props = new List<PropertyInfo>(myType.GetProperties());

        foreach (PropertyInfo prop in props)
        {
            if (prop.PropertyType == typeof(DelegateCommand))
            {
                var cmd = (DelegateCommand)prop.GetValue(this, null);
                cmd.RasieCanExecuteChanged();
            }

        }

Это хорошо работает для всех не типовых свойств DelegateCommand, но, конечно, не влияет на DelegateCommand<T>.

У меня вопрос Как определить, что свойство имеет тип DelegateCommand<T> и приведено к этому конкретному типу, чтобы иметь возможность вызывать RasieCanExecuteChanged?

Ответы [ 2 ]

7 голосов
/ 23 февраля 2012

Вы можете проверить, является ли тип свойства производным от DelegateCommandBase, и если это так - привести его к DelegateCommandBase и вызвать RaiseCanExecuteChanged.

Type myType = this.GetType();
IList<PropertyInfo> props = new List<PropertyInfo>(myType.GetProperties());

foreach (PropertyInfo prop in props)
{
    if (prop.PropertyType.IsSubclassOf(typeof(DelegateCommandBase)))
    {
        var cmd = (DelegateCommandBase)prop.GetValue(this, null);
        cmd.RaiseCanExecuteChanged();
    }
}
0 голосов
/ 22 мая 2015

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

https://stackoverflow.com/a/30394333/1716620

благодаря этому вы получите команду, подобную этой:

this.SaveCommand = new MyDelegateCommand<MyViewModel>(this,
    //execute
    () => {
      Console.Write("EXECUTED");
    },
    //can execute
    () => {
      Console.Write("Checking Validity");
       return PropertyX!=null && PropertyY!=null && PropertyY.Length < 5;
    },
    //properties to watch
    (p) => new { p.PropertyX, p.PropertyY }
 );

, таким образом, вы получите точный контроль над тем, какая переменная может повлиять на команду, без необходимости помещать много шаблонного кода или вызывать RaiseCanExecuteChanged, когдане требуется

...