我正在尝试将Delay-Property用于WPF绑定。在以下示例中,两个文本框绑定到同一属性。第一个使用延迟属性,第二个不使用延迟属性。
延迟效果很好。但意外的行为是,更改TextBox1中的值不会立即启用Button但TextBox2会启用。单击鼠标,输入键或使用tab键离开文本框将启用该按钮。
任何人都知道如何解决这个问题或原因是什么?
查看:
<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">
<StackPanel>
<TextBox x:Name="TextBox1" Text="{Binding Value1, UpdateSourceTrigger=PropertyChanged, Delay=1000}"/>
<TextBox x:Name="TextBox2" Text="{Binding Value1, UpdateSourceTrigger=PropertyChanged}"/>
<Button Command="{Binding ButtonCommand}" Content="GO!"></Button>
</StackPanel>
代码隐藏:
public partial class MainWindow : Window, INotifyPropertyChanged
{
private const decimal InitialValue = 400;
private decimal _value1;
public decimal Value1
{
get { return _value1; }
set
{
_value1 = value;
OnPropertyChanged();
}
}
public ICommand ButtonCommand { get; set; }
public MainWindow()
{
InitializeComponent();
Value1 = InitialValue;
ButtonCommand = new RelayCommand(x => { /*Do something*/ }, x => Value1 != InitialValue);
DataContext = this;
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
答案 0 :(得分:1)
问题是WPF命令系统“CanExecute”检查是由Control
事件触发的,而不是由ViewModel中的更改触发的。
所以会发生什么,你输入一个数字,触发一个事件。绑定触发响应,但由于延迟,它不会立即更新ViewModel属性。
不幸的是,该命令的“CanExecute”检查(RelayCommand
构造函数的第二个参数中的委托)也会响应您输入的数字而发生,Value1
尚未更改,因此按钮保持灰色,因为Value1
仍然等于初始值。延迟通过并Value1
更改后,“CanExecute”不会重新检查。
您可以将CommandManager.InvalidateRequerySuggested();
添加到Value1
设置器,它应该可以正常运行:
set
{
_value1 = value;
OnPropertyChanged();
CommandManager.InvalidateRequerySuggested();
}
答案 1 :(得分:0)
我建议你的RelayCommand是microsoft的默认实现。因此x => Value1 != InitialValue
是Func<bool> _canExecute
条件。
在_canExecute条件发生变化后,您可能需要提升RaiseCanExecuteChanged
的{{1}}事件。它不酷,但我认为应该工作。