Предотвратить выполнение команды кнопки из OnClick при выполнении условия

У меня есть команда RoutedUI, которая связана как свойство Command для кнопки и события OnClick. Всякий раз, когда я оцениваю какое-либо условие из OnClick, я хочу предотвратить выполнение команды. Я сослался на этот пост, но не очень помог wpf">Предотвратить выполнение команды. Одним из быстрых решений является получение отправителя кнопки при нажатии и установка для ее команды значения 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.
}
        }

person nikhil    schedule 18.10.2018    source источник
comment
e.Handled = true; работает на вас?   -  person ingvar    schedule 18.10.2018
comment
Пробовал, но все равно не помогает.   -  person nikhil    schedule 18.10.2018
comment
в любом случае лучше добавить поддержку для выполнения, как здесь отключить кнопку"> stackoverflow.com/questions/31807332/   -  person ingvar    schedule 18.10.2018
comment
Спасибо позвольте мне попробовать.   -  person nikhil    schedule 18.10.2018
comment
почему бы просто не использовать return;   -  person BladeMight    schedule 18.10.2018
comment
return все равно выполнит команду, если она привязана к xaml.   -  person nikhil    schedule 18.10.2018


Ответы (1)


Предполагая, что ваш метод StartRun() следует шаблону async/await, замените реализацию 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);
}

Подробнее читайте в моем сообщении в блоге.

person Peregrine    schedule 18.10.2018