Skip to content
This repository has been archived by the owner on Sep 20, 2021. It is now read-only.

Could anyone suggest a neat way to Dis-/Enable buttons #83

Open
DeputyOfCopyPaster opened this issue Feb 20, 2020 · 3 comments
Open

Could anyone suggest a neat way to Dis-/Enable buttons #83

DeputyOfCopyPaster opened this issue Feb 20, 2020 · 3 comments

Comments

@DeputyOfCopyPaster
Copy link

DeputyOfCopyPaster commented Feb 20, 2020

Hello everyone,
could anyone suggest a neat way to dis-/enable buttons?
Currently I'm doing such things as follows:

ViewModel:

// Properties
 public bool Save_btn_is_enabled
        {
            get { return _save_btn_is_enabled; }
            set { Set(ref _save_btn_is_enabled, value); }
        }
        private bool _save_btn_is_enabled;

// Constructor
Window_ViewModel()  
{
 DoSomething_command  = new RelayCommand(DoSomethingMethod);
 Save_btn_is_enabled = true;

}

//  do something method
privat async void DoSomethingMethod()
{
   Save_btn_is_enabled = false;

   // do smth here before dealying

 await Task.Delay(clickActionDelay1)

  // do smth here after delaying

 Save_btn_is_enabled = true;
}
@bobonline19
Copy link

ICommand and RelayCommand have a Func<bool> canExecute as well as an Action execute. When a button binds to an ICommand the enabled state binds to CanExecute and is updated on the CanExecuteChanged event. See the MVVM light sample RaiseCanExecuteChanged Sample

@DeputyOfCopyPaster
Copy link
Author

IMHO, this is quite bad example on how this works. Also I couldn't open this sample with VS2015.
Perhaps does anyone have better ones?

@thatsjohnson
Copy link

thatsjohnson commented Jun 30, 2021

@DeputyOfCopyPaster from your example it looks like you are trying to disable access while an async action is in process. If that is the case what you are doing is perfectly fine. Here is an example using ICommand that does not allow concurrent execution.
Example

XAML

<Button
    Text="Give me coffee !" 
    Command="{Binding Submit}" />

CODE

public interface IAsyncCommand : ICommand
{
    Task ExecuteAsync();
    bool CanExecute();
}
public class AsyncCommand : IAsyncCommand
{
    public event EventHandler CanExecuteChanged;

    private bool _isExecuting;
    private readonly Func<Task> _execute;
    private readonly Func<bool> _canExecute;
    private readonly IErrorHandler _errorHandler;

    public AsyncCommand(
        Func<Task> execute,
        Func<bool> canExecute = null,
        IErrorHandler errorHandler = null)
    {
        _execute = execute;
        _canExecute = canExecute;
        _errorHandler = errorHandler;
    }

    public bool CanExecute()
    {
        return !_isExecuting && (_canExecute?.Invoke() ?? true);
    }

    public async Task ExecuteAsync()
    {
        if (CanExecute())
        {
            try
            {
                _isExecuting = true;
                await _execute();
            }
            finally
            {
                _isExecuting = false;
            }
        }

        RaiseCanExecuteChanged();
    }

    public void RaiseCanExecuteChanged()
    {
        CanExecuteChanged?.Invoke(this, EventArgs.Empty);
    }

#region Explicit implementations
    bool ICommand.CanExecute(object parameter)
    {
        return CanExecute();
    }

    void ICommand.Execute(object parameter)
    {
        ExecuteAsync().FireAndForgetSafeAsync(_errorHandler);
    }
#endregion
}
public class MainViewModel : ViewModelBase
{
    private bool _isBusy;
    public bool IsBusy
    {
        get => _isBusy;
        private set => Set(ref _isBusy, value);
    }

    public IAsyncCommand Submit { get; private set; }

    public MainViewModel()
    {
        Submit = new AsyncCommand(ExecuteSubmitAsync, CanExecuteSubmit);
    }

    private async Task ExecuteSubmitAsync()
    {
        try
        {
            IsBusy = true;
            var coffeeService = new CoffeeService();
            await coffeeService.PrepareCoffeeAsync();
        }
        finally
        {
            IsBusy = false;
        }
    }

    private bool CanExecuteSubmit()
    {
        return !IsBusy;
    }
}

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants