66

In WPF data binding, I can bind the IsChecked property to some data, e.g. user setting, but I need to handle "CheckChanged" event, I know I can seperately handle Checked, Unchecked event, but is there any way to get notified when this value is changed?

<CheckBox Content="Case Sensitive" IsChecked="{Binding bSearchCaseSensitive,
          Source={x:Static Properties:Settings.Default}}" />

Note: I don't care if it is checked or unchecked. I just want to be notified when it is changed.

David
  • 15,894
  • 22
  • 55
  • 66
  • 1
    What do you want that for? why don't you bind the `IsChecked` property to something in the ViewModel and react to that property? UI is not Data. – Federico Berasategui Mar 18 '13 at 15:20
  • It is already bound to user setting. UI is not data, is this related to the question raised? – David Mar 18 '13 at 15:22
  • 3
    My point is that if the ViewModel needs to be aware when that changes, you should really bind that to the ViewModel, and not to a static thing, then from within the VM you could change the static value. – Federico Berasategui Mar 18 '13 at 15:26
  • I don't want to change the value, I want to handle the changed event and do sth else, for instance, a message box is shown. Do you have any suggestions to hook this event? – David Mar 18 '13 at 15:27
  • Noted with thanks. But I am trying to see if there can be even concise solution. – David Mar 18 '13 at 15:37
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/26387/discussion-between-david-and-highcore) – David Mar 18 '13 at 15:38

6 Answers6

122

That you can handle the checked and unchecked events seperately doesn't mean you have to. If you don't want to follow the MVVM pattern you can simply attach the same handler to both events and you have your change signal:

<CheckBox Checked="CheckBoxChanged" Unchecked="CheckBoxChanged"/>

and in Code-behind;

private void CheckBoxChanged(object sender, RoutedEventArgs e)
{
  MessageBox.Show("Eureka, it changed!");
}

Please note that WPF strongly encourages the MVVM pattern utilizing INotifyPropertyChanged and/or DependencyProperties for a reason. This is something that works, not something I would like to encourage as good programming habit.

nvoigt
  • 75,013
  • 26
  • 93
  • 142
37

As a checkbox click = a checkbox change the following will also work:

<CheckBox Click="CheckBox_Click" />
private void CheckBox_Click(object sender, RoutedEventArgs e)
{
    // ... do some stuff
}

It has the additional advantage of working when IsThreeState="True" whereas just handling Checked and Unchecked does not.

Martin Schneider
  • 14,263
  • 7
  • 55
  • 58
Rob
  • 3,488
  • 3
  • 32
  • 27
  • What happens if Checkbox if disabled but you click it? I guess the event still fires, which is not the desired behaviour, most of the times – Mario Garcia May 12 '17 at 08:36
  • 1
    That shouldn't happen. If it's disabled, click event will also be disabled. – Expenzor Jul 22 '17 at 13:48
  • 4
    It does have the correct behavior for disabled controls and when the keyboard is used. The significant difference between this and a general "state change" event is that the event doesn't fire when the checkbox is changed programmatically. – fadden Jun 26 '19 at 21:05
15

Im putting this in an answer because it's too long for a comment:

If you need the VM to be aware when the CheckBox is changed, you should really bind the CheckBox to the VM, and not a static value:

public class ViewModel
{
    private bool _caseSensitive;
    public bool CaseSensitive
    {
        get { return _caseSensitive; }
        set
        {
            _caseSensitive = value;
            NotifyPropertyChange(() => CaseSensitive);

            Settings.Default.bSearchCaseSensitive = value;
        }
    }
}

XAML:

<CheckBox Content="Case Sensitive" IsChecked="{Binding CaseSensitive}"/>
Federico Berasategui
  • 43,562
  • 11
  • 100
  • 154
  • 2
    @HighScore, Thanks, this is a solution, but overkill for my case. I don't want to resort to INotifyPropertyChanged, it is too cumbersome. :) – David Mar 18 '13 at 15:35
  • 4
    @David What? how are you handling WPF two-way binding without `INotifyPropertyChanged`? Also, that's got nothing to do with the example, it's just there because it's a ViewModel property. My example works just fine if you remove that. – Federico Berasategui Mar 18 '13 at 15:37
  • 1
    It is true, this is two way binding. the setting can be both read and written, with a pity that I am not notified of the setter change. – David Mar 18 '13 at 15:54
  • @RalfdeKleine, I don't know what is the point of your comment, as is already pointed out by others. – David May 23 '13 at 08:40
  • @RalfdeKleine, I never state that. – David May 23 '13 at 13:40
11

I know this is an old question, but how about just binding to Command if using MVVM?

ex:

<CheckBox Content="Case Sensitive" Command="{Binding bSearchCaseSensitive}"/>

For me it triggers on both Check and Uncheck.

user1568891
  • 386
  • 6
  • 12
2

A simple and proper way I've found to Handle Checked/Unchecked events using MVVM pattern is the Following, with Caliburn.Micro :

 <CheckBox IsChecked="{Binding IsCheckedBooleanProperty}" Content="{DynamicResource DisplayContent}" cal:Message.Attach="[Event Checked] = [Action CheckBoxClicked()]; [Event Unchecked] = [Action CheckBoxClicked()]" />

And implement a Method CheckBoxClicked() in the ViewModel, to do stuff you want.

Syph3r-
  • 21
  • 1
0

What about the Checked event? Combine that with AttachedCommandBehaviors or something similar, and a DelegateCommand to get a function fired in your viewmodel everytime that event is called.

dowhilefor
  • 10,971
  • 3
  • 28
  • 45
  • As commented in the question, I don't want to use Checked/Unchecked event handler, what I cared is the "changed" signal. – David Mar 18 '13 at 15:24