带延迟的WPF绑定无法正常工作

时间:2015-04-16 12:22:30

标签: c# wpf binding

我正在尝试将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));
    }
}

2 个答案:

答案 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 != InitialValueFunc<bool> _canExecute条件。

在_canExecute条件发生变化后,您可能需要提升RaiseCanExecuteChanged的{​​{1}}事件。它不酷,但我认为应该工作。