Thursday, April 22, 2010

Troubles in ToggleButton land

I was recently developing an application in WPF that uses a TabControl control as a ribbon-style navigation bar. I wanted the user to press a ToggleButton and a Frame control at the bottom of the Window would load the requested Page.

Since the TabControl would serve as a navigation bar, I wanted the user to visually be able to see which page was loaded by having the ToggleButton in a Pressed state.
So far so well. When pressing the ToggleButton it remained pressed (as it should).

Now, I wanted when the user pressed a different button, the previously pressed button to go to the Default state. Alas, when the new button was pressed, the previous button was in the Default state, but there was a highlight rectangle around it.

I didn't want to mess around with styles, I actually liked the visual appearance as is. I should note here that I am developing on Windows 7 with Visual Studio 2008. I have not tried this on other versions of Windows. After a lengthy investigation and endless google-ing without being able to find out anything, I found a post that mentioned if you set the IsChecked property to false, you then need to focus on the previous control.

So, I ended up creating a method that is called on each ToggleButton's Checked event, passing the ToggleButton as a parameter. This method compares all the ToggleButton with the parameter, and if they are not equal, sets the IsChecked property to false and calls the ToggleButton's Focus() method.
As a last step, I needed to call the calling ToggleButton's Focus() method, and, problem solved!

Here is a small code sample:

// highLightButton is used to de-press the other ToggleButtons
// except the parameter ToggleButton
private void highLightButton(ToggleButton toHighlight)
    if (toHighlight != btnOne)
        btnOne.IsChecked = false;
    if (toHighlight != btnTwo)
        btnTwo.IsChecked = false;
    if (toHighlight != btnThree)
        btnThree.IsChecked = false;

private void btnOne_Checked(object sender, RoutedEventArgs e)

private void btnTwo_Checked(object sender, RoutedEventArgs e)

private void btnThree_Checked(object sender, RoutedEventArgs e)

Another option is to set the Focusable property of each ToggleButton to false. Of course, this means that you cannot use keyboard focus events (Tabs).

No comments:

Post a Comment