WPF Richtextbox FontFace / FontSize

Actualmente estoy intentando crear algunas funciones básicas del procesador de textos en un proyecto de WPF. Estoy usando un RichTextBox y estoy al tanto de todos los EditingCommands (ToggleBold, ToggleItalic … ect.). En lo que estoy atascado es permitir que el usuario cambie el tamaño de fuente y la fuente como en MS Office, donde el valor cambia solo para el texto seleccionado y si no hay texto seleccionado, el valor cambiará para la posición actual del cursor. He ideado una cantidad decente de código para hacer que esto funcione, pero tengo problemas con el texto sin seleccionar. Esto es lo que estoy haciendo para 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); 

Entonces mi pregunta es ¿cómo debo hacer para hacer esto? ¿Hay una manera mejor / más conveniente de hacer esto? Uno de los pensamientos que tuve fue que necesitaría insertar un nuevo Inline en el párrafo, pero no pude averiguar cómo hacerlo. Cualquier ayuda es apreciada. Gracias.

Acabo de tener exactamente el mismo problema. Pude usar TextElement.FontSizeProperty como dijo bendewey. Sin embargo, todavía no estaba funcionando del todo bien. Después de mirar a través del proyecto en el enlace de abajo, descubrí que todavía estaba haciendo algo mal. No estaba poniendo el foco de nuevo en RichTextBox … que el autor del proyecto a continuación no tenía que hacer porque estaban usando un cuadro combinado de cinta. Con un cuadro combinado regular, después de seleccionar una fuente, realmente cambia la fuente de la selección en el RichTextBox, pero quita el foco del RTB. Cuando vuelve a hacer clic en el RTB para obtener el foco y comienza a escribir, tiene un nuevo objeto de selección, en cuyo caso la fuente vuelve a la fuente predeterminada del propio RTB.

http://www.codeplex.com/WPFRichEditorLibrary

Prueba esto

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

@ sub-jp tiene razón, debe volver a establecer el enfoque en RichTextBox , de lo contrario cambiará las propiedades de una selección, pero cuando haga clic nuevamente en el cuadro de texto, obtendrá una nueva selección con la fuente existente . Intenta cambiar tu código para ser así:

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

… y luego debería funcionar correctamente tanto cuando hay texto resaltado como cuando no lo hay.

Alternativamente, como se sugiere aquí , puede establecer la propiedad Focusable del ComboBox en False , para evitar este problema por completo.

He resuelto esto de la siguiente manera:

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

Tuve un problema similar, si te estoy entendiendo correctamente. Intenté buscar un montón de respuestas diferentes que estaban cerca pero que no me funcionaron del todo. Mi problema fue que el cambio de fuente funcionó bien para el texto que se seleccionó explícitamente, pero si no había texto seleccionado y se cambió el tamaño de la fuente, el siguiente texto ingresado volvería al tamaño de fuente predeterminado. Esto es lo que finalmente descubrí, dale una oportunidad y hazme saber si funcionó para alguien más:

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

El problema es que debe volver a establecer el foco en el cuadro de texto enriquecido después de seleccionar la nueva familia de fonts o el tamaño de fuente:

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

Es fácil de resolver si está manejando 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 :) } 

EDITAR: establecer CaretPosition al final de TextRange , puede hacer que Caret alinee incorrectamente a veces. Mi RichTextBox tiene muchos ajustes de BaselineAlignment de BaselineAlignment de BaselineAlignment por lo que podría haber sido lo que causó la mía. Pero, si alguna vez experimenta algún salto de Caret divertido o se hunde, trate de verificar si el Caret está al final del Paragraph cada vez antes de configurar el CaretPosition correctamente. Algo como esto funcionaría:

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

Sé que mi respuesta es tarde y todo, pero espero haber ayudado a alguien más. ¡Aclamaciones!