Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disable selected checkbox on button click

Just started working with the MVVM design pattern and I'm stuck.

When my application launches, I have a treeview populated with a list of objects names. I've setup the IsChecked Binding, and it works fine. I'm trying to setup the IsEnabled Binding.

I want the user to select the items in the treeview he wants, then click one of three buttons to perform an action. On click, I want the selected items to remain in the treeview, but be disabled, so the user cannot perform another action on those items.

I'm using a RelayCommand class in the application.

private ICommandOnExecute _execute;
private ICommandOnCanExecute _canExecute;

public RelayCommand(ICommandOnExecute onExecuteMethod, 
    ICommandOnCanExecute onCanExecuteMethod)
{
    _execute = onExecuteMethod;
    _canExecute = onCanExecuteMethod;
}

#region ICommand Members

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

public bool CanExecute(object parameter)
{
    return _canExecute.Invoke(parameter);
}

public void Execute(object parameter)
{
    _execute.Invoke(parameter);
}

#endregion

My object model class uses this

private bool _isEnabled;
public bool IsEnabled
{
    get { return true; }
    set { _isEnabled = value};
}

Then within my button method I have

if (interfaceModel.IsChecked)
{
    //Does Something
    MyObjectName.IsEnabled = false;
}

And here is my xaml

<CheckBox IsChecked="{Binding IsChecked}" IsEnabled="{Binding IsEnabled, Mode=TwoWay}">
    <TextBlock Text="{Binding MyObjectName}" Margin="5,2,1,2" HorizontalAlignment="Left" />
</CheckBox>
like image 415
David Russell Avatar asked Dec 05 '25 13:12

David Russell


1 Answers

You need a setup like this:

// Your ViewModel should implement INotifyPropertyChanged
class ViewModel : INotifyPropertyChnaged
{
    private bool _isEnabled;
    public bool IsEnabled
    {
        get { return _isEnabled; }
        set 
        { 
             _isEnabled = value;
             SetPropertyChanged("IsEnabled");  // Add this to your setter.
        }
    }

    // This comes from INotifyPropertyChanged - the UI will listen to this event.
    public event PropertyChangedEventHandler PropertyChanged;
    private void SetPropertyChanged(string property)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged( this, new PropertyChangedEventArgs(property) );
        }
    }
}

Note that PropertyChanged comes from having your ViewModel implement INotifyPropertyChanged. To notify the UI, you have to raise that event, and tell it what property was changed (usually in the setter - see above).

Alternatively, if you don't like raw strings (I don't, personally), you can use generics and expression trees to do something like this:

public void SetPropertyChanged<T>(Expression<Func<T, Object>> onProperty) 
{
    if (PropertyChanged != null && onProperty.Body is MemberExpression) 
    {
        String propertyNameAsString = ((MemberExpression)onProperty.Body).Member.Name;
        PropertyChanged(this, new PropertyChangedEventArgs(propertyNameAsString));
    }
}

Where in your setter you can say:

public bool IsEnabled
{    
    set 
    { 
        _isEnabled = value;
        SetPropertyChanged<ViewModel>(x => x.IsEnabled);  
    }
}

And now it's strongly typed, which is kinda nice.

like image 95
sircodesalot Avatar answered Dec 08 '25 16:12

sircodesalot



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!