views:

215

answers:

1

I'm creating a simple editor within our application using the WPF RichTextBox. Above it I've added the reguslar buttons like Bold, Italic, etc. These buttons use the RichTextBox's commands to set these properties, but next to these buttons, the commands also get send with CTRL+B, CTRL+I, etc. I want these buttons to represent the current state of the RichTextBox at the cursor. I already found out how to get this state and it works when I update this state on the SelectionChanged event. This event ofcourse isn't fired when Bold is toggled so there is no direct feedback.

I would like to know if there is a way to listen to the commands being called, without affecting its original behaviour or some other ideas to solve my problems.

I tried listening to the command the following way:

   CommandBinding boldBinding = new CommandBinding(EditingCommands.ToggleBold, CommandExecuted);
  _richTextBox.CommandBindings.Add(boldBinding);   

and

private void CommandExecuted(object sender, ExecutedRoutedEventArgs e) {
  UpdateProperties();
  e.Handled = false;      
}

This did update the properties, but the RichTextBox didn't seem to receive the command anymore.

I also tried to make my own commands on the control containing the RichTextBox, but when CTRL+B is pressed when the RichTextBox has focus, the original RichTextBox commands are called instead of the new one.

Many thanks in advance!

Liewe

+1  A: 

In order to listen to the commands being called, you can use the events raised by CommandManager: Executed or PreviewExecuted.

If you change your XAML to:

<RichTextBox x:Name="_richTextBox" ... 
    CommandManager:PreviewExecuted="OnRichTextBoxCommand" ... />

you get the OnRichTextBoxCommand method called right before the command is executed. Unfortunately, using the Executed attached event does not work.

This method is called for each event, so you have to filter them:

    private void OnRichTextBoxCommand(object sender, ExecutedRoutedEventArgs e) {

        if (e.Command == EditingCommands.ToggleBold) {
            UpdateProperties();
        }
    }

It may be even a bit more complex, as the current selection may not have changed when this method is called, so you have to post yourself a message, e.g. like this:

            Dispatcher.BeginInvoke(new Action(UpdateProperties));

(if you reference already System.Core, you have the Action type, otherwise define a delegate taking no parameter and returning void, and use in instead.)

Timores
This does the trick! Thank you very much!
Liewe