Gre*_*eri 9 wpf command prism mvvm
我有一个简单的窗口,带有一个带有命令的ViewModel按钮.
我希望如果MyCommand.CanExecute()为false,则禁用该按钮.但似乎WPF只会在首次绘制窗口时设置IsEnabled属性.任何后续操作都不会影响按钮的可见状态.我正在使用Prism的DelegateCommand.
我的看法:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button Content="Click Here" Command="{Binding MyCommand}" Width="100" Height="50"/>
</Grid>
Run Code Online (Sandbox Code Playgroud)
和我的ViewModel:
public class MyVM : NotificationObject
{
public MyVM()
{
_myCommand = new DelegateCommand(DoStuff, CanDoStuff);
}
private void DoStuff()
{
Console.WriteLine("Command Executed");
_myCommand.RaiseCanExecuteChanged();
}
private bool CanDoStuff()
{
var result = DateTime.Now.Second % 2 == 0;
Console.WriteLine("CanExecute is {0}", result);
return result;
}
private DelegateCommand _myCommand;
public ICommand MyCommand
{
get
{
return _myCommand;
}
}
}
Run Code Online (Sandbox Code Playgroud)
50%的时间,当我的应用程序加载时,按钮被正确禁用.但是,如果在窗口加载时启用它,并且我单击按钮执行命令,我希望该按钮有50%的时间被禁用,但它永远不会.该命令不会执行,但我仍然可以单击该按钮.当CanExecute()为false时,如何让WPF理解应该禁用该按钮?
我看你使用棱镜和NotificationObject和DelegateCommand的,所以我们应该期望有没有在RaiseCanExecuteChanged一个bug().
但是,行为的原因是Prism的RaiseCanExecuteChanged同步运行,因此 CanDoStuff()当我们仍然在执行中时调用,ICommand.Execute()然后结果似乎被忽略.
如果您使用自己的命令创建另一个按钮并_myCommand.RaiseCanExecuteChanged()从该命令/按钮调用,则第一个按钮将按预期启用/禁用.
或者,如果您使用MVVM Light和RelayCommand尝试相同的操作,您的代码将起作用,因为MVVM Light的RaiseCanExecuteChanged调用CommandManager.InvalidateRequerySuggested()会调用CanDoStuff异步使用的回调,从而Dispatcher.CurrentDispatcher.BeginInvoke避免了您在Prism实现中看到的行为.