Changing the font size to highlight RichTextBox through ComboBox does not work properly

I created a very simple WPF window consisting of a grid containing one RichTextBox and one ComboBox . I use ComboBox to change and find the font size in a RichTextBox .

Here is the code for my XAML file:

 public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); // Add the font sizes. for (var i = 1; i < 72; i++) { FontSize.Items.Add((double) i); } } private void MyTextBox_SelectionChanged(object sender, RoutedEventArgs e) { // If the selection changes, update the font size in the ComboBox. FontSize.SelectedValue = (double) MyTextBox.Selection.GetPropertyValue(TextBlock.FontSizeProperty); } private void FontSize_SelectionChanged(object sender, SelectionChangedEventArgs e) { // If the selected size changes, change the size of the selection in the RichTextBox. if (FontSize.SelectedItem != null) MyTextBox.Selection.ApplyPropertyValue(TextBlock.FontSizeProperty, FontSize.SelectedItem); } } 

There are two things here:

  • MyTextBox_SelectionChanged updates the ComboBox with the font size of the selection.
  • FontSize_SelectionChanged changes the font size of the selection.

You can see the problem below:

enter image description here

When I make a choice and change the font size, it changes perfectly. But the moment I click on another text with a different font size, it changes again.

What causes this behavior?

Edit: Here is the XAML file:

 <Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Grid> <ComboBox x:Name="FontSize" HorizontalAlignment="Left" VerticalAlignment="Top" Width="497" Margin="10,10,0,0" SelectionChanged="FontSize_SelectionChanged"/> <RichTextBox x:Name="MyTextBox" HorizontalAlignment="Left" Height="273" VerticalAlignment="Top" Width="497" Margin="10,37,0,0" RenderTransformOrigin="0.358,0.48" SelectionChanged="MyTextBox_SelectionChanged"> <FlowDocument> <Paragraph> <Run Text="RichTextBox"/> </Paragraph> </FlowDocument> </RichTextBox> </Grid> </Window> 

Edit 2: Here is a brief explanation of what I did when debugging it:

  • There are two debug points, one on MyTextBox_SelectionChanged and one on FontSize_SelectionChanged .
  • When I change the font size, I press F5 and continue.
  • When I click on another piece of text (default size), MyTextBox_SelectionChanged is MyTextBox_SelectionChanged . Selection.Text empty.
  • Then I continue again and stop when calling FontSize_SelectionChanged . But still Selection.Text empty, but my old selection of "Rich" returns to the previous font size.

Edit 3: This issue is mentioned in the Sams Teach Yourself WPF 24 hours first print July 2008, p. 135, β€œCreating a text editor works as expected,” point 9. I did not understand the explanation there and created a short sample illustrating this specific problem.

+4
source share
2 answers

It looks like when you click to clear the selection, it calls the TextBox.SelectionChanged ( MyTextBox_SelectionChanged ) event handler, and Selection represents an empty selection (i.e. just an insertion point). Your handler sets the SelectedValue combo box using the empty selection font size, which is reasonable even if the selection is empty. (The insertion point still has a font size.)

Changing SelectedValue , of course, causes the ComboBox.Selection ( FontSize_SelectionChanged ) event handler to fire. And since this event handler does not have an easy way to distinguish between an event caused by a user selecting a new value, and an event caused by your code changing the SelectedValue property, it goes ahead and tries to change the font size of the selection, which you probably do not want to do in this particular case.

However, you would think that everything will be fine, because the choice is empty, and you are just trying to set its font size regardless of its font size. But here's the strange thing: when you call ApplyPropertyValue on this empty choice, it seems to set FontSize for the whole document.

So the effect is that when you click to clear the selection, your code sets the entire font size of the document as the font size at the point where you click.

I suspect the error is in ApplyPropertyValue , because this only happens if the initially selected text was selected by dragging from left to right, starting with the very first character. Again, it is not entirely clear what the behavior is if you apply formatting to an empty selection. So, perhaps this is most likely a case of invoking undefined behavior, rather than getting a specific error in WPF.

In any case, a reasonable way to fix this is to change the change handler with a list:

 if (FontSize.SelectedItem != null && !MyTextBox.Selection.IsEmpty) { MyTextBox.Selection.ApplyPropertyValue( TextBlock.FontSizeProperty, FontSize.SelectedItem); } 

This is just an attempt to resize the selection font if the selection is not empty.

+2
source

When you select your text and then resize it through the menu, your code is still selected, even if you no longer see the selection, now when you select your code, the SelectionChanged method fires before the MyTextBoxSelection changes, (i just guess / believe it I think I had such a problem once). Now you are changing the Fontsize and Fontsize method, which refers to the not updated Selection, invalidating your last change.

0
source

All Articles