简体   繁体   中英

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));
    }
}

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));
}

Since you are changing value of IsEnabled Property directly in code behind which breaks your binding

either use:

(this.DataContext as ButtonEnableViewModel).IsEnable = false; 

or restructure your code and change value of IsEnable property in viewModel itself.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM