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;
        btnOne.Focus();
    }
    if (toHighlight != btnTwo)
    {
        btnTwo.IsChecked = false;
        btnTwo.Focus();
    }
    if (toHighlight != btnThree)
    {
        btnThree.IsChecked = false;
        btnThree.Focus();
    }
    toHighlight.Focus();
}

private void btnOne_Checked(object sender, RoutedEventArgs e)
{
    highLightButton(btnOne);
}

private void btnTwo_Checked(object sender, RoutedEventArgs e)
{
    highLightButton(btnTwo);
}

private void btnThree_Checked(object sender, RoutedEventArgs e)
{
    highLightButton(btnThree);
}

Edit:
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