Проблемы с RichTextBox.Selection и TextSelection.ApplyPropertyValue

Я пытаюсь создать текстовый редактор в WPF, используя RichTextBox. Моя проблема с изменением размера шрифта моего текста. Мой код работает как задумано во всех случаях, кроме случаев, когда курсор находится внутри слова. В этом случае он не должен изменять размер шрифта для чего-либо, кроме размера шрифта текста, который приходит, если пользователь что-то пишет. Проблема в том, что по какой-то причине TextSelection.ApplyPropertyValue(RichTextBox.FontSizeProperty, value) изменяет размер шрифта всего слова, когда курсор находится внутри слова.

Это мой eventHandler:

private void fontSizeBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    ComboBox comboBox = (ComboBox)sender;
    string value = (string)comboBox.SelectedValue;

    if (comboBox.IsDropDownOpen)
    {
        TextSelection text = textBoxMain.Selection;
        richTextBox.Focus();
        text.ApplyPropertyValue(RichTextBox.FontSizeProperty, value);
    }            
}

И я не могу использовать что-то вроде добавления !text.Text.IsEmpty внутри оператора if, потому что мне все еще нужно иметь возможность изменять размер шрифта для текста, который будет написан.

Я нашел похожие вопросы на StackOverFlow, но ни один с реальным рабочим ответом.

Изменить: добавлен XAML

<Window x:Class="MathEdit.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:MathEdit"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Window.CommandBindings>
    <CommandBinding Command="Open" Executed="OpenCommandBinding_Executed"></CommandBinding>
    <CommandBinding Command="Save" Executed="SaveCommandBinding_Executed"></CommandBinding>
    <CommandBinding Command="SaveAs" Executed="SaveAsCommandBinding_Executed"></CommandBinding>
</Window.CommandBindings>

<Window.InputBindings>
    <KeyBinding Key="O" Modifiers="Control" Command="Open"></KeyBinding>
    <KeyBinding Key="S" Modifiers="Control" Command="Save"></KeyBinding>
    <KeyBinding Key="S" Modifiers="Control+Alt" Command="SaveAs"></KeyBinding>
</Window.InputBindings>

<DockPanel>
    <Menu DockPanel.Dock="Top">
        <MenuItem Header="_File">
            <MenuItem Header="_New" InputGestureText="Ctrl+N" />
            <MenuItem Header="_Open" InputGestureText="Ctrl+O" Command="Open"/>
            <MenuItem Header="_Save" InputGestureText="Ctrl+S" Command="Save"/>
            <MenuItem Header="_Save As" InputGestureText="Ctrl+Alt+S" Command="SaveAs"/>
            <Separator />
            <MenuItem Header="_Exit" InputGestureText="Alt+F4" />
        </MenuItem>
        <MenuItem Header="_Tools">
            <MenuItem Header="_Check if toby = on" IsCheckable="false" IsChecked="True" Click="MenuItem_Click" />
            <MenuItem Header="_Settings" Click="MenuItem_Click_2" IsCheckable="True" />
            <MenuItem Header="_Add formula" x:Name="menuItemAdd" Click="MenuItem_Add_Click" />
        </MenuItem>
        <ComboBox x:Name="fontSizeBox" Width="40" SelectedValuePath="Content" SelectionChanged="fontSizeBox_SelectionChanged" SelectedIndex="2">
            <ComboBoxItem Content="5"/>
            <ComboBoxItem Content="12"/>
            <ComboBoxItem Content="16"/>
            <ComboBoxItem Content="20"/>
        </ComboBox>
    </Menu>
    <Grid x:Name="gridParent">
    <RichTextBox x:Name="richTextBox" AcceptsReturn="True" SelectionChanged="textBoxMain_SelectionChanged" />
    </Grid>
</DockPanel>

1 ответ

Решение

Это простое применение значения свойства к нетекстовой выборке невозможно. Посмотрите, что вы получите, когда примените его к реальному выбору: скажем, у вас есть текст "Привет, храбрый новый мир". Документ внутри RTB выглядит так (упрощенно)

<FlowDocument>
  <Paragraph>
    <Run>hello brave new world</Run>
  </Paragraph>
</FlowDocument>

Когда вы выбираете "смелый" и изменяете размер шрифта (или что-то еще), документ изменяется на

<FlowDocument>
  <Paragraph>
    <Run>hello </Run>
    <Run FontSize="20">brave</Run>
    <Run> new world</Run>
  </Paragraph>
</FlowDocument>

Атрибут должен быть применен к некоторому тексту; нет способа изменить "ничего", как вы просили. Если вы хотите добиться того, что для меня наиболее близко соответствует вашим требованиям, вам придется разделить документ самостоятельно - когда выбор пуст - и создать пустой прогон с нужным размером шрифта. Таким образом, приведенный выше пример будет выглядеть так (при условии, что каретка расположена перед "храбрым"):

<FlowDocument>
  <Paragraph>
    <Run>hello </Run>
    <Run FontSize="20"></Run>
    <Run>brave new world</Run>
  </Paragraph>
</FlowDocument>

Так как это оставляет бесконечные возможности получить бесконечное количество "пустых" прогонов, я бы посоветовал пересмотреть ваше требование.

Другие вопросы по тегам