满足条件时阻止按钮命令从OnClick执行

时间:2018-10-18 19:16:54

标签: c# wpf xaml routed-commands

我有一个RoutedUI命令,该命令绑定为按钮和OnClick事件的Command属性。每当我从OnClick评估某些条件时,我都想阻止命令执行。我提到了这篇文章,但对Prevent command execution没有多大帮助。一种快速的解决方法是单击按钮的发送方,并将其命令设置为null。但是我想知道是否还有其他方法。请帮忙。

 <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.
}
        }

1 个答案:

答案 0 :(得分:0)

假设您的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上的更多详细信息。