WPF Richtextbox FontFace / FontSize

我目前正在尝试在WPF项目中创建一些基本的文字处理器function。 我正在使用RichTextBox并且知道所有的EditingCommands(ToggleBold,ToggleItalic等等)。 我坚持的事情是允许用户像在MS Office中那样更改字体大小和字体,其中值仅针对所选文本进行更改,如果没有选定文本,则值将更改为当前插入位置。 我已经提出了相当数量的代码来使这个工作,但我没有选择文本的问题。 这是我正在为RichTextBox.Selection做的事情。

TextSelection text = richTextBox.Selection; if (text.IsEmpty) { //doing this will change the entire word that the current caret position //is on which is not the desire/expected result. text.ApplyPropertyValue(RichTextBox.FontSizeProperty, value); } else //This works as expected. text.ApplyPropertyValue(RichTextBox.FontSizeProperty, value); 

所以我的问题是我应该怎么做呢? 有没有更好/更方便的方法来做到这一点? 我有一个想法是我需要在段落中插入一个新的内联,但我无法弄清楚如何做到这一点。 任何帮助表示赞赏。 谢谢。

我刚才有同样的问题。 bendewey说,我能够使用TextElement.FontSizeProperty。 但是,它仍然没有正常工作。 在查看下面链接的项目后,我发现我还在做错事。 我没有将焦点设置回RichTextBox …下面项目的作者不需要这样做,因为他们使用的是一个function区combobox。 使用常规combobox,在选择字体后,它实际上会更改RichTextBox中选择的字体,但它会将焦点从RTB中移开。 当您单击RTB以获得焦点并开始键入时,您有一个新的选择对象,在这种情况下,字体将恢复为RTB本身的默认字体。

http://www.codeplex.com/WPFRichEditorLibrary

试试这个

 var range = new TextRange( richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd ); range.ApplyPropertyValue( TextElement.FontSizeProperty, value ); 

@ sub-jp是正确的,您需要将焦点设置回RichTextBox ,否则您将更改一个选择的属性,但是当您单击返回文本框时,您将获得具有现有字体的新选择。 尝试将代码更改为:

 TextSelection text = richTextBox.Selection; richTextBox.Focus(); text.ApplyPropertyValue(RichTextBox.FontSizeProperty, value); 

…然后它应该在突出显示文本和没有文本时正常工作。

或者, 如此处所示 ,您可以将ComboBox的Focusable属性设置为False ,以完全避免此问题。

我解决了这个问题如下:

 TextRange r = new TextRange(richtextbox.Selection.Start, richtextbox.Selection.End); r.ApplyPropertyValue(TextElement.FontSizeProperty, value); 

如果我理解正确,我也有类似的问题。 我试着搜索大量各种各样的答案,这些答案很接近,但对我来说并不适用。 我的问题是字体更改适用于明确选择的文本,但如果没有选定的文本,并且字体大小已更改,则输入的以下文本将恢复为默认的fontsize。 这是我最终想出来的,试一试,让我知道它是否适用于其他任何人:

  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(); } 

问题是在选择新的FontFamily或字体大小后,必须将焦点设置回Rich Textbox:

 //When Font Size is changed private void rbngFontSize_SelectionChanged(object sender, SelectionChangedEventArgs e) { rtbMain.Focus(); // This part is what fixes the issue, just make sure it is set before ApplyPropertyValue method. try { ApplyPropertyValueToSelectedText(TextElement.FontSizeProperty, e.AddedItems[0]); } catch { }; } //When FontFamily is changed private void rbngFontFamily_SelectionChanged(object sender, SelectionChangedEventArgs e) { FontFamily editValue = (FontFamily)e.AddedItems[0]; rtbMain.Focus(); // This part is what fixes the issue, just make sure it is set before ApplyPropertyValue method. ApplyPropertyValueToSelectedText(TextElement.FontFamilyProperty, editValue); } 

如果您正在处理OnTextInput这很容易解决。

 protected override void OnTextInput(TextCompositionEventArgs e) { TextRange range = new TextRange(this.Selection.Start, this.Selection.End); // Doesn't matter whether the selection is empty or not, it should be // replaced with something new, and with the right formatting range.Text = e.Text; // Now nothing else would get affected... range.ApplyPropertyValue(TextElement.FontFamilyProperty, value); this.CaretPosition = range.End; e.Handled = true; // You might not need this line :) } 

编辑:将CaretPosition设置为TextRange的末尾,有时可能会使Caret对齐错误。 我的RichTextBox有很多BaselineAlignment调整,所以这可能是导致我的。 但是,如果您遇到任何有趣的Caret跳跃或下沉,请在每次正确设置CaretPosition之前检查Caret是否在ParagraphCaretPosition 。 这样的东西会起作用:

 TextRange test = new TextRange(range.End, range.End.Paragraph.ContentEnd); bool IsAtEnd = test.IsEmpty || String.IsNullOrEmpty(test.Text) || test.Text == "\r\n"; // Now we know whether the Caret is still in the middle of the text or not // This part corrects the Caret glitch! :) if (!IsAtEnd) this.CaretPosition = range.End; else this.CaretPosition = range.Start.GetNextContextPosition(LogicalDirection.Forward); 

我知道我的答案很晚,但希望我帮助了别人。 干杯!