Ribbon Toggle Button state

Ribbon for WPF Forum

Posted 10 years ago by sbarry
Avatar
I have buttons in the ribbon that represent a toggle state (bold, italic, etc.). I have noticed that when the button's checked state is false, when clicking on the button there is a bit of flashing that happens. The same behavior happens in the ribbon samples as well. I believe it's because the Execute is fired after the mouse up, so the button doesn't stay pressed when you let the mouse up. Then, the execute is fired, followed by the can execute with causes the button to go into the checked state.

I would like the button to not show an unchecked state on the mouse up. Instead, could the command execute be fired before the button is unchecked in the mouse up event?

Microsoft Word and other Office products exhibit the behavior I'm looking for. Thanks!

Here is the code that handles the check state:

private void ExecuteBoldCommand(object sender, ExecutedRoutedEventArgs e)
        {
            // This happens after the mouse up event and the button always has 
            // an unchecked state when this code executes.  Subsequent 
            // CanExecuteBoldCommand will set state to checked (if it should be) 
            // causing the flickering.
            DoBoldExecute();
        }

        private void CanExecuteBoldCommand(object sender, CanExecuteRoutedEventArgs e)
        {
            CheckableCommandParameter checkableParameter = e.Parameter as CheckableCommandParameter;

            if (checkableParameter != null)
            {
                if (_style != null)
                {
                    checkableParameter.IsChecked = IsFontStyleOn(StyleProperties.Bold);
                }
                else
                {
                    checkableParameter.IsChecked = false;
                }
                checkableParameter.Handled = true;
            }

            if (_style == null)
            {
                e.CanExecute = false;
            }
            else
            {
                e.CanExecute = ExecutionUtility.CanExecuteBoldCommand();
            }
        }
[Modified at 12/04/2009 09:40 AM]

Comments (3)

Posted 10 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
The problem here is that mouse up raises the Click event. The code the calls the Click event dispatches the call since normally, you want the button to repaint if it's command handler opening a dialog, etc. Thus there is a brief delay before your command handler gets called which is not desired in your scenario.

I'm not sure we'd want to auto-check the button because there is a chance no handler for the button will be available to properly update its checked state if the auto-check is wrong. We default to providing a CheckableCommandParameter to buttons, so there's no easy way to know whether that auto-check functionality would be desired or not, unless we added a new property to make it auto check.

Now the code that calls the Click event in a dispatched fashion, calls OnPreviewClick right in the main non-dispatched thread beforehand. I'm wondering if you could raise your command's CanExecute from a handler in that as a workaround. It would fire the CanExecute twice since our Click code would follow up with another call, but that may allow it to update quicker.


Actipro Software Support

Posted 10 years ago by sbarry
Avatar
I tried your suggestion. The problem is that we actually have to execute the command to get the new toggle state. I think the fundamental problem is that a mouse click changes the visual state of the toggle button before the IsChecked is resolved through the CanExecute. This behavior is desired for a regular button, but not for toggle buttons.

What I'm looking for is a Toggle Button object in which no Mouse Click events (MouseDown, MouseClick, MouseUp) affect the visual state of the button. The visual state is only affected by the IsChecked property through the CanExecute handler.

Do you have a suggestion on how to achieve this?

Thanks!
Posted 10 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
You'd probably have to get our default button templates, clone them, and change them to not have triggers for certain mouse events. Then tell your desired buttons to use a custom Style that assigned that other template.

If you are a WPF Studio suite customer, you can always download the current styles/templates right from your Organization Purchases page.


Actipro Software Support

The latest build of this product (v2019.1 build 0683) was released 1 month ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.