将可绑定属性与命令同步

问题描述 投票:0回答:1
有没有办法在属性以指定的绑定延迟发生变化时执行命令?

作为示例,我们使用具有 IsChecked 属性且 Delay=1000(1 秒)的 CheckBox 和在 IsChecked 属性更改时调用的 Command:

MainWindow.xaml:

<CheckBox Command="{Binding Command}" Content="Hello" IsChecked="{Binding IsChecked, Delay=1000}" />
MainWindow.xaml.cs:

private bool _isChecked; public bool IsChecked { get { return _isChecked; } set { if (_isChecked != value) { _isChecked = value; OnPropertyChanged(); MessageBox.Show("Property Changed"); } } } public ICommand Command { get; } = new RelayCommand(obj => MessageBox.Show("Command Invoked"));
单击复选框时,首先调用 MessageBox.Show("Command Invoked"),然后调用 MessageBox.Show("Property Changed");

最终输出:

"Command Invoked" -\> after 1 sec delay -\> "Property Changed"


    

c# wpf xaml data-binding binding
1个回答
0
投票
您可以从属性

set()

执行操作,具体取决于
Binding
的延迟。

或者您使用计时器显式延迟操作或

Task.Delay

:

public ICommand SomeCommand { get; } = new RelayCommand(ExecuteSomeCommandDelayedAsync); private async Task ExecuteSomeCommandDelayedAsync(object commandParameter) { await Task.Delay(TimeSpan.FromSeconds(1)); MessageBox.Show("Command Invoked"); }
要复制绑定引擎的延迟行为,您必须使用计时器并在每次调用时重置它,并专门遵守最新的更改/命令参数:

public ICommand SomeCommand { get; } = new RelayCommand(ExecuteSomeCommand); // Important: this Timer implements IDisposable/IDisposableAsync. // It must be disposed if it is no longer needed! private System.Threading.Timer CommandDelayTimer { get; } private object SomeCommandCommandParameter { get; set; } public Constructor() => this.CommandDelayTimer = new Timer(OnCommandDelayElapsed); private async Task ExecuteSomeCommand(object commandParameter) { // Capture latest parameter value and drop the previous this.SomeCommandCommandParameter = commandParameter; // Start/reset the timer. // This timer is configured to execute only once (period time = 0). _ = this.CommandDelayTimer.Change(TimeSpan.FromSeconds(1), TimeSpan.Zero); } private void OnCommandDelayElapsed(object? state) { SomeCommandOperation(state); } // The operation that the command is supposed to invoke after a delay private void SomeCommandOperation(object commandParameter) { MessageBox.Show("Command Invoked"); }
    
© www.soinside.com 2019 - 2024. All rights reserved.