首页 > 解决方案 > 将 RichTextBox 的 SelectionChanged 事件和组合框的 TextChanged 事件用于 FontSize 会引发 DependencyProperty.UnsetValue 错误

问题描述

我正在编写有关WPF 的教程RichTextBox (RTB)。该教程中的两个事件一起DependencyProperty.UnsetValue在以下场景中引发错误:

场景:当我更改 中任意两个单词的字体大小时,当我RichTextBox (RTB)在 RTB 中手动选择这两个单词时,我在下面显示的事件中收到DependencyProperty.UnsetValue错误。cmbFontSize_TextChanged(...)但是如果我删除SelectionChangedRTB 的事件(如下所示)或注释掉 SelectionChanged 事件的最后两行(与字体大小有关),则不会发生错误。

问题:我们真的需要以下SelectionChanged事件的最后两行(与字体大小有关)吗?或者,我们还能如何解决这个问题?我测试了没有这两行,应用程序成功地更改了任何选定文本的字体大小(即使它有不同字体大小的单词)并且不会在事件中引发DependencyProperty.UnsetValue错误 。cmbFontSize_TextChanged(...)

备注:我已经上传了这个场景的最小示例。如何测试:在 RTB 上,复制/粘贴:Word1 and Word2 in one sentence.将 Word2 的大小更改为不同的大小(例如 16)。选择Word1 and Word2零件的那一刻,您将收到以下错误:

在此处输入图像描述

主窗口.xaml

<Window x:Class="WpfApp_Test4RTB.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp_Test4RTB"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <DockPanel>
        <ToolBar DockPanel.Dock="Top">
            <TextBlock Text="Font Size:"/>
            <ComboBox Name="cmbFontSize" Width="50" IsEditable="True" TextBoxBase.TextChanged="cmbFontSize_TextChanged" />
        </ToolBar>
        <RichTextBox Name="rtbEditor" SelectionChanged="rtbEditor_SelectionChanged" />
    </DockPanel>
</Window>

主窗口.xaml.cs

public MainWindow()
{
    InitializeComponent();
    cmbFontSize.ItemsSource = new List<double>() { 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72 };
    cmbFontSize.SelectedIndex = 4;
}

private void rtbEditor_SelectionChanged(object sender, RoutedEventArgs e)
{
    object temp = rtbEditor.Selection.GetPropertyValue(Inline.FontWeightProperty);
    btnBold.IsChecked = (temp != DependencyProperty.UnsetValue) && (temp.Equals(FontWeights.Bold));
    temp = rtbEditor.Selection.GetPropertyValue(Inline.FontStyleProperty);
    btnItalic.IsChecked = (temp != DependencyProperty.UnsetValue) && (temp.Equals(FontStyles.Italic));
    temp = rtbEditor.Selection.GetPropertyValue(Inline.TextDecorationsProperty);
    btnUnderline.IsChecked = (temp != DependencyProperty.UnsetValue) && (temp.Equals(TextDecorations.Underline));

    temp = rtbEditor.Selection.GetPropertyValue(Inline.FontFamilyProperty);
    cmbFontFamily.SelectedItem = temp;
    temp = rtbEditor.Selection.GetPropertyValue(Inline.FontSizeProperty);
    cmbFontSize.Text = temp.ToString();
}

private void cmbFontSize_TextChanged(object sender, TextChangedEventArgs e)
{
    rtbEditor.Selection.ApplyPropertyValue(TextElement.FontSizeProperty, cmbFontSize.Text);
}

标签: c#wpfrichtextbox

解决方案


问题不在于事件。

您想将字符串类型的值分配给 double 属性。
尝试double num =" 12.34 ";在代码中做 - 会有错误。您正在尝试在这里做同样的事情。
实际上在错误信息中它的原因已经写得很详细了。
在将字符串分配给数值变量或属性之前,必须首先对其进行转换。

但是在您的任务中,这是没有意义的,因为您正在从双重集合中获取值。
只需检查是否做出了选择,如果是,则分配选定的值。

private void cmbFontSize_TextChanged(object sender, TextChangedEventArgs e)
{
    if(cmbFontSize.SelectedItem is double number)
        rtbEditor.Selection.ApplyPropertyValue(TextElement.FontSizeProperty, number);
}

推荐阅读