Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I attach commands to the checking and unchecking of a CheckBox?

In my ViewModel I have two commands:

ICommand ExecuteMeOnCheck { get; }
ICommand ExecuteMeOnUncheck { get; }

I wish to attach these commands to a CheckBox and have one of them execute when it is checked and the other execute when it is unchecked. What's the best way to achieve this without cluttering the View with code-behind?

like image 568
GraemeF Avatar asked Jun 06 '09 10:06

GraemeF


3 Answers

I did this with a Trigger on "IsChecked" that sets the Command.

e.g.

<Style x:Key="checkBoxStyle" TargetType="{x:Type CheckBox}">
      <Style.Triggers>
        <Trigger Property="IsChecked" Value="True">
          <Setter Property="Command"
                  Value="{Binding AddThingCommand}" />
        </Trigger>
        <Trigger Property="IsChecked" Value="False">
          <Setter Property="Command"
                  Value="{Binding RemoveThingCommand}" />
        </Trigger>
      </Style.Triggers>
    </Style>
like image 186
Timje Avatar answered Sep 27 '22 18:09

Timje


The simplest way I have found to do this involves borrowing a bunch of code. I also think that you do not want to expose two events for the state change. Make your command CheckedChangedCommand instead of Checked and Unchecked. Bind the CheckBox.IsChecked dependency property to a property on your ViewModelClass. That way when your command gets executed, you just check that value in your ViewModel.

First, start using DelegateCommand from the WPF ViewModel toolkit. It isn't clear from your post whether you are or not.

Next, download the .zip archive from the Downloads tab at this link.

The archive has a class called EventBehaviourFactory that makes setting the DependencyProperty easier. Back on the Home tab at the above link, Samuel tells you how to wire up the Command in your XAML to the ViewModel. Here it is:

<TextBox ff:TextBoxBehaviour.TextChangedCommand="{Binding TextChanged}"/>

I used the three classes (DelegateCommand, EventBehaviourFactory and TextBoxBehaviour) line for line and had the TextChanged event working in my project in about five minutes.

The pattern for extending it to other controls like you need to do is easy too. I managed to wire up ListBox.SelectionChanged the same way. Create a new ControlBehaviour class and substitute "Control" for "TextBox" in all the instances and attach the DependencyProperty to the new event.

It is a beautiful thing when your code behind is empty!

like image 30
Eddie Butt Avatar answered Sep 27 '22 19:09

Eddie Butt


Another solution, similar to Eddie's : the Attached Command Behaviours by Marlon Grech

You could also use the CheckBox's Command property to attach only one command, in which you test whether the checkbox is checked...

Or you could bind the IsChecked property to a property of your ViewModel, and react to the change in the setter of that property.

like image 31
Thomas Levesque Avatar answered Sep 27 '22 19:09

Thomas Levesque