Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

WPF Checkboxes - Strange Behaviour

0.00/5 (No votes)
18 Nov 2014 1  
Something to look out for in WPF

Introduction

Yesterday, I set out to make what sounded like a very simple change to an existing WPF project and it turned out to be far from simple.

The mission was a straight-forward one - add an "are you sure?" prompt when users changed the setting of a checkbox in certain circumstances and revert the checkbox to its original setting should they decide against making the change.

The software in question is a rather scruffy implementation of WPF (one of those where the developer had tried to treat WPF as Winforms) so this is maybe not a problem that would occur in a purer WPF implementation but nonetheless, it was a highly annoying one so I thought that I'd note it for anyone else who might run into a similar situation.

The obvious approach here was to apply the business logic in the Checked/Unchecked event handler and revert the checkbox's IsChecked state when appropriate.

I duly inserted the code and ran the code. To my amazement, the checkbox started to behave in a way that was almost (but not quite) opposite to what was expected. I just couldn't figure out what was going on.

Well, it was a big mess of a project so it seemed reasonable to assume that something was resetting the value but I searched to no avail.

Using the Code

To ensure that there was no outside interference, I created a fresh project and reduced everything to a single Checkbox:

<CheckBox Name="cbTest" 
Checked="cbTestCheckChanged" Unchecked="cbTestCheckChanged"  />

In the code behind, to keep things simple, I just set the prompt to occur on any change:

private void cbTestCheckChanged(object sender, RoutedEventArgs e)
{
    MessageBoxResult result = MessageBox.Show
    ("Are you sure?", "Please confirm", MessageBoxButton.YesNo);

    if (result == MessageBoxResult.No)
        {
        //Disengage the event handler so we don't retrigger it ...

                cbTest.Checked -= cbTestCheckChanged;
                cbTest.Unchecked -= cbTestCheckChanged;

                //Change the state of the box
                cbTest.IsChecked = !cbTest.IsChecked;

                //Re-engage the handler
                cbTest.Checked += cbTestCheckChanged;
                cbTest.Unchecked += cbTestCheckChanged;
       }
} 

All that worked exactly as I'd expect it to, but then I had a suspicion. What would happen if I applied a theme to the project?

I duly applied the WhistlerBlue theme and found that the stripped solution was suddenly behaving with all the erraticness of the original. A quick run through of the various Codeplex themes showed that this bug was common to all of them.

By changing the mark-up to ignore styles, I could make it work:

<CheckBox Name="cbTest" Checked="cbTestCheckChanged" 
Unchecked="cbTestCheckChanged" Style="{x:Null}" />  

(This could also be achieved by setting the Style property to null in the code behind).

Well, that was a few hours wasted but at least I've learnt a lesson: if your WPF Checkboxes are misbehaving and you're using the WPF Theme pack, disable the theme before you investigate any further. The same thing, I'm pretty sure, will also apply to radio-buttons.

Points of Interest

Setting the OverridesDefaultStyle property will not work, the style must be nulled.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here