5

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

这里有两件事:

  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>

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

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

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

4

2 回答 2

3

What seems to be happening is that when you click to clear the selection, this causes your TextBox.SelectionChanged event handler (MyTextBox_SelectionChanged) to be invoked while the Selection represents an empty selection (i.e., just an insertion point). Your handler sets the combo box's SelectedValue, using the empty selection's font size, which is a perfectly reasonable thing to do even if the selection is empty. (The insertion point still has a font size.)

Changing the SelectedValue of course causes your ComboBox.Selection event handler (FontSize_SelectionChanged) to run. And because that event handler has no easy way to distinguish between an event caused by the user selecting a new value, and the event being caused by your code changing the SelectedValue property, it goes ahead and attempts to modify the selection's font size, which you probably don't want to be doing in this particular case.

Even so, you'd think it'd be OK, because the selection is empty, and you're just attempting to set its font size to be whatever its font size already is. But here's the weird thing: when you call ApplyPropertyValue on this empty selection, it appears to set the FontSize for the entire document.

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

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

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

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

如果选择不为空,这只会尝试更改选择的字体大小。

于 2013-04-01T14:32:13.080 回答
0

当您选择文本,然后在菜单上更改大小时,即使您不再看到选择,您的代码仍然被选中,现在当您选择代码时,SelectionChanged 方法会在 MyTextBoxSelection 更改之前触发,(我只是猜测/相信,我想我曾经遇到过这样的问题)。现在您更改 Fontsize 并触发 Fontsize 方法,该方法访问未更新的选择,使您的最后一次更改无效。

于 2013-03-30T10:41:28.860 回答