Как я могу изменить FontFamily в WPF RichTextBox без изменения предыдущего текста - PullRequest
2 голосов
/ 17 июля 2009

Когда вы используете свойство FontFamily RichTextBox, оно изменяет FontFamily всего содержимого внутри FlowDocument. Точно так же, как вы можете выполнить команду вроде EditingCommands.ToggleBold, где она меняет только слово под кареткой или только новый текст, который нужно записать, должен быть способ сделать то же самое с FontsFamilies и Color.

Ответы [ 3 ]

3 голосов
/ 22 июля 2009

Возможно, не самое удачное решение, но вы можете унаследовать его от RichTextBox и добавить немного поведения

Объявите свои собственные свойства шрифта, чтобы вы могли связать их позже со списком шрифтов

    public class CustomControl1 : RichTextBox
    {

public static readonly DependencyProperty CurrentFontFamilyProperty =
                DependencyProperty.Register("CurrentFontFamily", typeof(FontFamily), typeof  (CustomControl1), new FrameworkPropertyMetadata(new FontFamily("Tahoma"), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,new PropertyChangedCallback(OnCurrentFontChanged)));
    }

Переопределить OnTextInput. Вы не можете подписаться на это событие, так как RichTextBox имеет встроенную обработку для всплытия KeyDown и KeyUp, и между ними генерируется TextInput

    protected override void OnTextInput(TextCompositionEventArgs e)
{
        if (fontchanged)
        {
            TextPointer tp = this.CaretPosition.GetInsertionPosition(LogicalDirection.Forward);
            Run r = new Run(e.Text, tp);
            r.FontFamily = CurrentFontFamily;
            r.Foreground = CurrentForeground;
            this.CaretPosition = r.ElementEnd;
            fontchanged = false;
        }
        else
            base.OnTextInput(e);
    }

если ваш CurrentFontProperty изменился, найдите позицию каретки и создайте новый прогон с новым вводом текста и установите FontFamily = CurrentFontFamily. Вы также можете изменить слово целиком, если в нем есть слово над словом. В этой статье может быть интересно найти слово Навигация по словам в RichTextBox .

.
2 голосов
/ 17 ноября 2010

Вот что я использовал, чтобы избежать переопределения richtextbox. Это позволяет вам изменить стиль выделения, если он есть, или изменить стиль текста «для добавления» после каретки. Надеюсь, это поможет.

    public static void SetFontSize(RichTextBox target, double value)
    {
        // Make sure we have a richtextbox.
        if (target == null)
            return;

        // Make sure we have a selection. Should have one even if there is no text selected.
        if (target.Selection != null)
        {
            // Check whether there is text selected or just sitting at cursor
            if (target.Selection.IsEmpty)
            {
                // Check to see if we are at the start of the textbox and nothing has been added yet
                if (target.Selection.Start.Paragraph == null)
                {
                    // Add a new paragraph object to the richtextbox with the fontsize
                    Paragraph p = new Paragraph();
                    p.FontSize = value;
                    target.Document.Blocks.Add(p);
                }
                else
                {
                    // Get current position of cursor
                    TextPointer curCaret = target.CaretPosition;
                    // Get the current block object that the cursor is in
                    Block curBlock = target.Document.Blocks.Where
                        (x => x.ContentStart.CompareTo(curCaret) == -1 && x.ContentEnd.CompareTo(curCaret) == 1).FirstOrDefault();
                    if (curBlock != null)
                    {
                        Paragraph curParagraph = curBlock as Paragraph;
                        // Create a new run object with the fontsize, and add it to the current block
                        Run newRun = new Run();
                        newRun.FontSize = value;
                        curParagraph.Inlines.Add(newRun);
                        // Reset the cursor into the new block. 
                        // If we don't do this, the font size will default again when you start typing.
                        target.CaretPosition = newRun.ElementStart;
                    }
                }
            }
            else // There is selected text, so change the fontsize of the selection
            {
                TextRange selectionTextRange = new TextRange(target.Selection.Start, target.Selection.End);
                selectionTextRange.ApplyPropertyValue(TextElement.FontSizeProperty, value);
            }
        }
        // Reset the focus onto the richtextbox after selecting the font in a toolbar etc
        target.Focus();
    }
1 голос
/ 17 июля 2009

Вы бы использовали RUN внутри RichTextBox, что-то вроде:

<RichTextBox>
   <Run FontFamily="Arial">My Arial Content</Run>
   <Run FontFamily="Times" FontWeight="Bold">My bolded Times content</Run>
   <Run>My Content that inherits Font From the RTB</Run>
</RichTextBox>

Хорошо, можно поиграть с некоторыми низкоуровневыми хуями. Но здесь мы идем:

Сначала добавьте несколько кнопок ToggleButton и RichTextBox в форму XAML. В поле Rich Text Box вы дадите ему несколько командных привязок, чтобы система знала, что все работает вместе.

Вот XAML:

<RichTextBox Height="119" Name="RichTextBox1" Width="254" >
       <RichTextBox.CommandBindings>
            <CommandBinding Command="EditingCommands.ToggleBold" CanExecute="CommandBinding_CanExecute"   ></CommandBinding>
            <CommandBinding Command="EditingCommands.ToggleItalic" CanExecute="CommandBinding_CanExecute"   ></CommandBinding>
       </RichTextBox.CommandBindings>
</RichTextBox>
<ToggleButton MinWidth="40" Command="EditingCommands.ToggleBold"  Height="23" HorizontalAlignment="Left" Name="Button1" VerticalAlignment="Top" Width="75" CommandTarget="{Binding ElementName=RichTextBox1}" >Bold</ToggleButton>
<ToggleButton MinWidth="40" Command="EditingCommands.ToggleBold"  Height="23" HorizontalAlignment="Left"  Name="Button2" VerticalAlignment="Top" Width="75" CommandTarget="{Binding ElementName=RichTextBox1}" >Italics</ToggleButton>

Теперь, что есть RichTextbox и две кнопки переключения, и кнопки переключения связаны с привязками команд к ToggleBold / ToggleItalics индивидуально.

В коде у меня есть два метода:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)      
End Sub

Private Sub CommandBinding_CanExecute(ByVal sender As System.Object, ByVal e As System.Windows.Input.CanExecuteRoutedEventArgs)
     e.CanExecute = True
End Sub

Имеется обработчик события BUTTON CLICK, потому что кнопке нужен обработчик события, чтобы его можно было использовать.

CanExecute сообщает кнопке, доступно ли значение для полужирного шрифта или нет (например, вы можете проверить длину и не пытаться полужирным шрифтом, если RTB пуст).

Теперь, для действительно низкоуровневого управления вещами, вы должны будете делать вещи в RichTextFormat. Перейдите по этой ссылке , чтобы узнать больше об этом.

...