4

我正在使用 Prism 和 MVVM 开发 WPF 应用程序。

应用程序的要求之一是能够以不同的用户身份登录(具有不同的权限)。

现在大多数权限都是简单的允许或禁止显示特定视图。所有这些都作为DelegateCommand或有时作为DelegateCommand<T>

如果用户有权显示特定视图,则这些命令的 CanExecute 将返回 true。我也有一个持有用户信息和权限的单例 Sessionmanager。

当用户登录时,我正在使用 EventAggregator 触发一个事件。在所有 ViewModel 的基类中,我订阅了该事件并使用反射循环通过 VM 的所有公共属性(类型为 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?

4

2 回答 2

7

您可以检查属性的类型是否派生自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();
    }
}
于 2012-02-22T23:23:18.633 回答
0

我更喜欢另一种方法,即在视图模型上监视属性更改,然后仅在我监视的属性更改时才提高 raisecanexecutechanged,我在这里发布了有关它的信息:

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

于 2015-05-22T10:43:11.060 回答