我有一个带有WPF功能区的相当标准的WPF应用程序。在上述功能区中,我公开了一些按钮,这些按钮绑定到我的ViewModel和RelayCommands
(ApplicationCommands)上RoutedUICommands
的组合。
据我所知,只要Window
上发生输入事件(鼠标点击,按键),WPF就会重新查询命令的CanExcecute方法。
现在,我打算在输入时提高效果,我想使用Delay
上的Bindings
属性。
这是我开始看到我的问题的地方。想象一下以下场景:
我有一个命令,其中CanExecute根据以下条件返回true:
Text.Length % 2 == 0;
所以想象一下,Text是我ViewModel
上的一个属性。
我看到的细分是:
Text
上的ViewModel
属性会更新。如何确保在延迟之后调用CanExecute逻辑,而不是之前? 在某处有错误的假设吗?我似乎无法找到有同样问题的其他人,这让我感到奇怪。
我可以致电InvalidateRequerySuggested,但我没有看到这样做的好地方。当然不在我的ViewModels
。
编辑 - 更新实例
以下是重现问题的完整代码:
查看:
<Window x:Class="DelayBindings.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:delayBindings="clr-namespace:DelayBindings"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<delayBindings:MainWindowViewModel/>
</Window.DataContext>
<StackPanel>
<TextBox Text="{Binding Path=Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Delay=200}"/>
<Button Command="{Binding MyCommand}">MyCommand</Button>
<TextBlock>Count:</TextBlock>
<TextBlock Text="{Binding Text.Length}"/>
</StackPanel>
</Window>
视图模型:
public class MainWindowViewModel : INotifyPropertyChanged
{
private RelayCommand _myCommand;
private string _text;
public RelayCommand MyCommand
{
get { return _myCommand ?? (_myCommand = new RelayCommand(MyCommandExecuted, MyCommandCanExecute)); }
}
public string Text
{
get { return _text; }
set
{
_text = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("Text"));
}
}
}
public void MyCommandExecuted()
{
}
public bool MyCommandCanExecute()
{
return Text != null && Text.Length % 2 == 0;
}
public event PropertyChangedEventHandler PropertyChanged;
}
在大多数情况下,将延迟设置为200ms将有效地反转按钮的逻辑。
请注意,我希望找到这个问题的一般解决方案,因为我们的应用程序中有数千个命令。