如何在不修改以前的文本的情况下更改WPF RichTextBox中的FontFamily

时间:2009-07-17 14:17:48

标签: wpf fonts wpf-controls

当您使用RichTextBox的FontFamily属性时,它会更改FlowDocument中整个内容的FontFamily。 你可以用同样的方式执行一个命令,比如EditingCommands.ToggleBold,它只改变插入符号下的单词或者只改变要写入的新文本,应该有一种方法可以用FontsFamilies和Color做同样的事情。

3 个答案:

答案 0 :(得分:3)

也许不是最好的解决方案,但您可以从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已更改,请获取插入位置并使用新的文本输入创建新的Run并设置FontFamily = CurrentFontFamily。如果carret是一个单词,你也可以改变整个单词,这篇文章可能很有趣,可以发现单词Navigate Words in RichTextBox

答案 1 :(得分:2)

以下是我曾经避免覆盖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();
    }

答案 2 :(得分:1)

你在RichTextBox里面使用RUN,比如:

<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>

好的,这可以和一些低级别的hoick一起玩。但是我们走了:

首先,将一些ToggleButtons和一个RichTextBox添加到XAML表单中。在富文本框中,您将为其提供一些命令绑定,以便让系统知道一切都在一起工作。

这是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和两个切换按钮,并且togglebuttons分别与ToggleBold / ToggleItalics的命令绑定相关。

在CODE方面,我有以下两种方法:

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中做事。请按照此link了解详情。