Akhter
Akhter

Reputation: 43

Enable Button on RelayCommand WPF

Button is not getting enable on Command Enable, doEnable method. Click method is disabling button. Button IsEnabled is Bind with ViewModel public property IsEnable, which is setting true on doEnable. Kindly advise what is wrong in below Code

XAML:

<Button Content="{Binding DataText}" Height="30" Width="80" Command="{Binding Enable}" Click="ButtonBase_OnClick" IsEnabled="{Binding IsEnable}" ></Button>

Window2.cs:

public partial class Window2 : Window
{
    public Window2()
    {
        InitializeComponent();
        DataContext = new ButtonEnableViewModel();
    }

    private void ButtonBase_OnClick(object sender, RoutedEventArgs e) 
    {
        if(sender is Button btn)
            btn.IsEnabled = false;
    }
}

ButtonEnableViewModel.cs

class ButtonEnableViewModel : INotifyPropertyChanged 
{
    public ButtonEnableViewModel() 
    {
        IsEnable = true;
        DataText = "Click Here";
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChange(string name) 
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }

    private RelayCommand _enableCmd;
    public RelayCommand Enable => _enableCmd ?? (_enableCmd = new RelayCommand(doEnable));

    public bool IsEnable { get; set; }
    public string DataText { get; set; }

    protected void doEnable(object obj) 
    {
        IsEnable = true;
        DataText = "Clicked";
        OnPropertyChange(nameof(IsEnable));
        OnPropertyChange(nameof(DataText));
    }
}

Upvotes: 1

Views: 3294

Answers (1)

mm8
mm8

Reputation: 169240

You should generally use the CanExecute method of the command to disable the Button. Most implementations of the ICommand interface accepts a Predicate<object> that you can use to tell the command when to enable the command/button.

In this case you might simply remove the event handler from the code-behind though and just handle the command in the view model:

<Button Content="{Binding DataText}" Height="30" Width="80" Command="{Binding Enable}" IsEnabled="{Binding IsEnable}" />

This should work since you set the IsEnable property in the Execute method of the command and raise the PropertyChanged event. You generally don't handle Click events in the code-behind of the view when you bind to a command of a view model.

If you use the CanExecute method of the command, you don't need to bind to the IsEnable property:

<Button Content="{Binding DataText}" Height="30" Width="80" Command="{Binding Enable}" />

View Model:

private RelayCommand _enableCmd;
public RelayCommand Enable => _enableCmd ?? (_enableCmd = new RelayCommand(doEnable, x => _isEnabled));

private bool _isEnabled;
public string DataText { get; set; }

protected void doEnable(object obj)
{
    _isEnabled = true;
    Enable.RaiseCanExecuteChanged();
    DataText = "Clicked";
    OnPropertyChange(nameof(DataText));
}

Upvotes: 4

Related Questions