当满足条件时,阻止从 OnClick 执行按钮命令
Prevent button command from executing from OnClick when a condition is met
我有一个 RoutedUI 命令,它被绑定为按钮和 OnClick 事件的命令 属性。每当我从 OnClick 评估某些条件时,我都想阻止命令执行。我提到了这个 post 但没有太大帮助 。一种快速解决方法是在单击时获取按钮的发送者并将其命令设置为空。但我想知道是否有其他方法。请帮忙。
<Button DockPanel.Dock="Right"
Name="StartRunButtonZ"
VerticalAlignment="Top"
Style="{StaticResource GreenGreyButtonStyle}"
Content="{StaticResource StartARun}"
Width="{StaticResource NormalEmbeddedButtonWidth}"
Click="StartRunButton_Click"
Command="{Binding StartRunCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl},AncestorLevel=2}}"
/>
这是背后的代码
private void StartRunButton_Click(object sender, RoutedEventArgs e)
{
if(SomeCondition){
//Prevent the Command from executing.
}
}
假设您的 StartRun() 方法遵循异步/等待模式,然后将您的 ICommand 实现替换为以下内容。当任务为 运行 时,它将 CanExecute 设置为 false,这将自动禁用按钮。您不需要混合命令和单击事件处理程序。
public class perRelayCommandAsync : ViewModelBase, ICommand
{
private readonly Func<Task> _execute;
private readonly Func<bool> _canExecute;
public perRelayCommandAsync(Func<Task> execute) : this(execute, () => true) { }
public perRelayCommandAsync(Func<Task> execute, Func<bool> canExecute)
{
_execute = execute ?? throw new ArgumentNullException(nameof(execute));
_canExecute = canExecute;
}
private bool _isExecuting;
public bool IsExecuting
{
get => _isExecuting;
set
{
if(Set(nameof(IsExecuting), ref _isExecuting, value))
RaiseCanExecuteChanged();
}
}
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter) => !IsExecuting
&& (_canExecute == null || _canExecute());
public async void Execute(object parameter)
{
if (!CanExecute(parameter))
return;
IsExecuting = true;
try
{
await _execute().ConfigureAwait(true);
}
finally
{
IsExecuting = false;
}
}
public void RaiseCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
我的 blog post.
有更多详细信息
我有一个 RoutedUI 命令,它被绑定为按钮和 OnClick 事件的命令 属性。每当我从 OnClick 评估某些条件时,我都想阻止命令执行。我提到了这个 post 但没有太大帮助
<Button DockPanel.Dock="Right"
Name="StartRunButtonZ"
VerticalAlignment="Top"
Style="{StaticResource GreenGreyButtonStyle}"
Content="{StaticResource StartARun}"
Width="{StaticResource NormalEmbeddedButtonWidth}"
Click="StartRunButton_Click"
Command="{Binding StartRunCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl},AncestorLevel=2}}"
/>
这是背后的代码
private void StartRunButton_Click(object sender, RoutedEventArgs e)
{
if(SomeCondition){
//Prevent the Command from executing.
}
}
假设您的 StartRun() 方法遵循异步/等待模式,然后将您的 ICommand 实现替换为以下内容。当任务为 运行 时,它将 CanExecute 设置为 false,这将自动禁用按钮。您不需要混合命令和单击事件处理程序。
public class perRelayCommandAsync : ViewModelBase, ICommand
{
private readonly Func<Task> _execute;
private readonly Func<bool> _canExecute;
public perRelayCommandAsync(Func<Task> execute) : this(execute, () => true) { }
public perRelayCommandAsync(Func<Task> execute, Func<bool> canExecute)
{
_execute = execute ?? throw new ArgumentNullException(nameof(execute));
_canExecute = canExecute;
}
private bool _isExecuting;
public bool IsExecuting
{
get => _isExecuting;
set
{
if(Set(nameof(IsExecuting), ref _isExecuting, value))
RaiseCanExecuteChanged();
}
}
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter) => !IsExecuting
&& (_canExecute == null || _canExecute());
public async void Execute(object parameter)
{
if (!CanExecute(parameter))
return;
IsExecuting = true;
try
{
await _execute().ConfigureAwait(true);
}
finally
{
IsExecuting = false;
}
}
public void RaiseCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
我的 blog post.
有更多详细信息