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

我创建了一个非常简单的
WPF窗口,其中包含一个包含一个RichTextBox和一个ComboBox的Grid.我使用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);
    }
}

这里有两件事:

> MyTextBox_SelectionChanged使用选择的字体大小更新ComboBox.
> 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>

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

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

编辑3:在Sams Teach Yourself WPF in 24 Hours第一次打印2008年7月,第135页“使文本编辑器按预期工作”,第9项中提到了这个问题.我不明白那里的解释并创建了一个简短的示例来说明该特定问题.

最佳答案 似乎正在发生的是当您单击以清除选择时,这会导致调用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);
}

如果选择非空,则仅尝试更改选择的字体大小.

点赞