通过 ComboBox 更改 RichTextBox 选择的字体大小无法正常工作

hat*_*enn 5 c# wpf events xaml

RichTextBox我创建了一个非常简单的 WPF 窗口,由包含 1和 1的 Grid 组成ComboBox。我使用ComboBox来更改和查找RichTextBox所选内容的字体大小。

这是我的 XAML 的代码隐藏文件:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这里有两件事:

  1. MyTextBox_SelectionChangedComboBox使用所选内容的字体大小更新。
  2. FontSize_SelectionChanged更改所选内容的字体大小。

您可以看到下面的问题:

在此输入图像描述

当我做出选择并更改字体大小时,它会发生完美的变化。但是,当我单击另一个具有不同字体大小的文本时,它会再次变回来。

是什么导致了这种行为?

编辑:这是 XAML 文件:

<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>
Run Code Online (Sandbox Code Playgroud)

编辑2:这是我在调试时所做的简短解释:

  1. 有两个调试点,一个在MyTextBox_SelectionChanged,一个在FontSize_SelectionChanged。
  2. 当我更改字体大小时,我单击 F5 并继续。
  3. 当我单击文本的另一部分(具有默认大小)时,MyTextBox_SelectionChanged将被调用。是Selection.Text空的。
  4. 然后我再次继续并在对 的调用处停止FontSize_SelectionChanged。但仍然Selection.Text是空的,但我的旧选择“Rich”返回到旧的字体大小。

编辑 3:这个问题在Sams Teach Yourself WPF in 24 Hours首次印刷,2008 年 7 月,第 135 页,“ Making the Text Editor Work as Expected ”,第 9 项中提到。我不明白那里的解释,并创建了一个简短的示例来说明那个具体问题。

Ian*_*ths 3

似乎发生的情况是,当您单击以清除选择时,这会导致调用TextBox.SelectionChanged事件处理程序 ( MyTextBox_SelectionChanged),而Selection代表空选择(即,只是一个插入点)。您的处理程序使用空选择的字体大小来设置组合框的SelectedValue,即使选择为空,这也是完全合理的事情。(插入点仍然有字体大小。)

更改SelectedValue当然会导致您的ComboBox.Selection事件处理程序 ( FontSize_SelectionChanged) 运行。由于该事件处理程序没有简单的方法来区分由用户选择新值引起的事件和由代码更改属性引起的事件SelectedValue,因此它会继续尝试修改所选内容的字体大小,您可能会这样做不想在这种特殊情况下做。

即便如此,您仍然会认为没关系,因为选择是空的,并且您只是尝试将其字体大小设置为已有的字体大小。但奇怪的是:当您调用这个空选择时,它似乎为整个文档ApplyPropertyValue设置了。FontSize

因此,效果是,当您单击以清除选择时,您的代码会将整个文档的字体大小设置为您单击时的字体大小。

我怀疑这是 中的一个错误ApplyPropertyValue,因为只有当您最初选择的文本是通过从第一个字符开始从左到右拖动来选择时才会发生这种情况。话又说回来,如果您将格式应用于空选择,则并不完全清楚该行为意味着什么。因此,也许这只是调用未定义行为的情况,而不是遇到 WPF 中的明确错误。

无论如何,解决此问题的合理方法是修改组合框更改处理程序:

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

如果选择非空,则这只尝试更改选择的字体大小。