Pro
Pro

Reputation: 727

Button becomes disabled after executing command

Sometimes the button (Done) becomes disabled after the click event.

I also have to click on the form again in order to re-enable the button.

Here is my code:

Button behavior

XAML:

<Button
    Grid.Column="1"
    Height="20"
    Margin="10,5"
    Command="{Binding DoneCommand}"
    Content="Done" />

C#:

private readonly RaiseCommand doneCommand;
private readonly BackgroundWorker worker;

private object _currentUserState;
private int _currentProgress;

public RaiseCommand DoneCommand
{
    get { return doneCommand; }
}

public MainWindowViewModel()
{
    doneCommand = new RaiseCommand(o => worker.RunWorkerAsync(), o => !worker.IsBusy);

    worker = new BackgroundWorker();
    worker.DoWork += DoDoneCommand;
    worker.ProgressChanged += ProgressChanged;
    worker.RunWorkerCompleted += RunWorkerCompleted;
    worker.WorkerReportsProgress = true;
}

private void DoDoneCommand(object sender, DoWorkEventArgs e)
{
    MessageBox.Show("test");
}

private void ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    CurrentUserState = e.UserState;
    CurrentProgress = e.ProgressPercentage;
}

private void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{

}

EDIT:

My command class.

This class is processing my commands of XAML.

It implements ICommand interface.

public class RaiseCommand : ICommand
{
    readonly Action<object> _action;
    readonly Func<object, bool> _canExecute;

    public RaiseCommand(Action<object> execute) : this(execute, null) { }

    public RaiseCommand(Action<object> execute, Func<object, bool> canExecute)
    {
        _action = execute ?? throw new ArgumentNullException("execute");
        _canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        return _canExecute == null ? true : _canExecute(parameter);
    }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public void Execute(object parameter)
    {
        _action(parameter);
    }
}

Upvotes: 0

Views: 97

Answers (1)

mm8
mm8

Reputation: 169400

You could call the CommandManager.InvalidateRequerySuggested() method in your RunWorkerCompleted method to force the CommandManager to refresh the state of all commands:

private void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    CommandManager.InvalidateRequerySuggested();
}

Or you could use an ICommand implementation that provides a method to raise the CanExecuteChanged event, such as for example Prism's DelegateCommand or MvvmLight's RelayCommand.

Upvotes: 1

Related Questions