我正在使用Prism和MVVM开发WPF应用程序。
该应用程序的一个要求是能够以不同的用户身份登录(具有不同的权限)。
现在大多数权限都是简单的允许或禁止显示特定视图。
所有这些都实现为DelegateCommand
或有时DelegateCommand<T>
如果用户有权显示特定视图,那么这些命令的CanExecute将返回true。 我还有一个包含用户信息和权限的单一Sessionmanager。
当用户登录时,我使用EventAggregator触发事件。 在所有ViewModel的基类中,我订阅了该事件并使用了反射 循环遍历DelegateCommand类型的VM的所有公共属性,并为该命令调用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?
答案 0 :(得分: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();
}
}
答案 1 :(得分: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