Comment gérer la mise en forme RichText (gras / italique / etc.) lors de la modification d’un élément?

J’ai une zone de texte riche qui peut contenir une chaîne contenant des éléments en gras, en italique ou même des fonts et des tailles différentes. Si je sélectionne la chaîne entière, y compris toutes les différences, comment puis-je “mettre en gras” cette chaîne sans convertir la chaîne entière en police générique avec juste un atsortingbut “gras”?

Par exemple: je veux transformer “Ceci est du text ” en ” Ceci est du text

Notez que “is some” est resté en italique et que “text” est resté dans une police différente.

Ce que j’ai actuellement est assez simpliste:

 private void tsBold_Click(object sender, EventArgs e) { if (rtb.SelectionFont == null) return; Font f; if (tsBold.Checked) f = new Font(rtb.SelectionFont, FontStyle.Bold); else f = new Font(rtb.SelectionFont, FontStyle.Regular); rtb.SelectionFont = f; rtb.Focus(); } 

Bien sûr, cela va appliquer la même police exacte à toute la sélection. Est-il possible d’append simplement “gras” à la (aux) police (s) existante (s)?

RÉPONSE Bien que la réponse “officielle” ci-dessous ne soit que la partie visible de l’iceberg, c’était le coup de pouce dont j’avais besoin dans la bonne direction. Merci pour le tuyau.

Voici mon correctif officiel:

J’ai ajouté ceci à mon object RichTextBox:

  ///  /// Change the richtextbox style for the current selection ///  public void ChangeFontStyle(FontStyle style, bool add) { //This method should handle cases that occur when multiple fonts/styles are selected // Parameters:- // style - eg FontStyle.Bold // add - IF true then add else remove // throw error if style isn't: bold, italic, ssortingkeout or underline if (style != FontStyle.Bold && style != FontStyle.Italic && style != FontStyle.Ssortingkeout && style != FontStyle.Underline) throw new System.InvalidProgramException("Invalid style parameter to ChangeFontStyle"); int rtb1start = this.SelectionStart; int len = this.SelectionLength; int rtbTempStart = 0; //if len <= 1 and there is a selection font then just handle and return if (len <= 1 && this.SelectionFont != null) { //add or remove style if (add) this.SelectionFont = new Font(this.SelectionFont, this.SelectionFont.Style | style); else this.SelectionFont = new Font(this.SelectionFont, this.SelectionFont.Style & ~style); return; } using (EnhancedRichTextBox rtbTemp = new EnhancedRichTextBox()) { // Step through the selected text one char at a time rtbTemp.Rtf = this.SelectedRtf; for (int i = 0; i < len; ++i) { rtbTemp.Select(rtbTempStart + i, 1); //add or remove style if (add) rtbTemp.SelectionFont = new Font(rtbTemp.SelectionFont, rtbTemp.SelectionFont.Style | style); else rtbTemp.SelectionFont = new Font(rtbTemp.SelectionFont, rtbTemp.SelectionFont.Style & ~style); } // Replace & reselect rtbTemp.Select(rtbTempStart, len); this.SelectedRtf = rtbTemp.SelectedRtf; this.Select(rtb1start, len); } return; } 

J’ai ensuite changé les méthodes de clic pour utiliser le modèle suivant:

  private void tsBold_Click(object sender, EventArgs e) { enhancedRichTextBox1.ChangeFontStyle(FontStyle.Bold, tsBold.Checked); enhancedRichTextBox1.Focus(); } 

RTB ne supporte pas cela aussi bien. Vous ne pouvez même pas découvrir la plage de caractères dans la sélection qui a le même style de police. Commencez par vérifier d’abord la propriété SelectionFont. Elle sera nulle si la sélection contient un mélange de styles. Si tel est le cas, vous devrez itérer la sélection caractère par caractère en définissant les propriétés SelectionStart et SelectionLength, lisez le champ SelectionFont jusqu’à ce qu’il soit modifié. Appliquez la police modifiée à la plage que vous avez découverte.

Cochez cette réponse pour trouver un moyen de garder cela raisonnablement rapide et sans scintillement.

Notez que l’implémentation d’un éditeur avec RTB est un sujet de prédilection sur codeproject.com. Emprunter du code, si ce n’est tout le projet, est un bon moyen de réduire la douleur.

Pour mettre une sélection de texte en gras tout en conservant sa mise en forme, utilisez ceci:

 if (rtb.SelectionFont !=null) rtb.SelectionFont = new Font(rtb.SelectionFont, rtb.SelectionFont.Style | FontStyle.Bold); 

Pour annuler la sélection de texte en gras tout en conservant sa mise en forme, utilisez ceci:

 if (rtb.SelectionFont !=null) rtb.SelectionFont = new Font(rtb.SelectionFont, rtb.SelectionFont.Style & ~FontStyle.Bold); 

Notez que le code ci-dessus ne fonctionnera que si tout le texte sélectionné a la même mise en forme (taille de la police, style, etc.). Ceci est détecté en vérifiant d’abord la propriété SelectionFont, elle sera nulle si la sélection contient un mélange de styles.

Maintenant, faites cela avec tout le texte dans richtextbox,

Désactivez / désactivez le texte entier de richtextbox tout en conservant l’intégralité du formatage, vous devez parcourir tous les caractères de la richtextbox et appliquer un par un les caractères Bold / unBold. Voici le code complet:

 private void tsBold_Click(object sender, EventArgs e) { //Loop through all the characters of richtextbox for (int i = 0; i < rtb.TextLength; i++) { //Select current character rtb.Select(i, 1); if (tsBold.Checked) //Make the selected character Bold rtb.SelectionFont = new Font(rtb.SelectionFont, rtb.SelectionFont.Style | FontStyle.Bold); else //Make the selected character unBold rtb.SelectionFont = new Font(rtb.SelectionFont, rtb.SelectionFont.Style & ~FontStyle.Bold); } } 

Si vous devez basculer l'état existant en gras (c.-à-d. Rendre le texte non gras en gras et rendre le texte en gras non gras), utilisez plutôt ceci:

  if (rtb.SelectionFont.Style.ToSsortingng().Contains("Bold")) //If the selected character is Bold //Make the selected character unBold rtb.SelectionFont = new Font(rtb.SelectionFont, rtb.SelectionFont.Style & ~FontStyle.Bold); else //If the selected character is unBold //Make the selected character Bold rtb.SelectionFont = new Font(rtb.SelectionFont, rtb.SelectionFont.Style | FontStyle.Bold); 

Si vous souhaitez également modifier la famille et la taille de police, vous pouvez utiliser cette méthode: Hans a raison, vous devez itérer chaque caractère.

  private void ChangeFontStyleForSelectedText(ssortingng familyName, float? emSize, FontStyle? fontStyle, bool? enableFontStyle) { _maskChanges = true; try { int txtStartPosition = txtFunctionality.SelectionStart; int selectionLength = txtFunctionality.SelectionLength; if (selectionLength > 0) using (RichTextBox txtTemp = new RichTextBox()) { txtTemp.Rtf = txtFunctionality.SelectedRtf; for (int i = 0; i < selectionLength; ++i) { txtTemp.Select(i, 1); txtTemp.SelectionFont = RenderFont(txtTemp.SelectionFont, familyName, emSize, fontStyle, enableFontStyle); } txtTemp.Select(0, selectionLength); txtFunctionality.SelectedRtf = txtTemp.SelectedRtf; txtFunctionality.Select(txtStartPosition, selectionLength); } } finally { _maskChanges = false; } } ///  /// Changes a font from originalFont appending other properties ///  /// Original font of text /// Target family name /// Target text Size /// Target font style /// true when enable false when disable /// A new font with all provided properties added/removed to original font private Font RenderFont(Font originalFont, ssortingng familyName, float? emSize, FontStyle? fontStyle, bool? enableFontStyle) { if (fontStyle.HasValue && fontStyle != FontStyle.Regular && fontStyle != FontStyle.Bold && fontStyle != FontStyle.Italic && fontStyle != FontStyle.Underline) throw new System.InvalidProgramException("Invalid style parameter to ChangeFontStyleForSelectedText"); Font newFont; FontStyle? newStyle = null; if (fontStyle.HasValue) { if (fontStyle.HasValue && fontStyle == FontStyle.Regular) newStyle = fontStyle.Value; else if (originalFont != null && enableFontStyle.HasValue && enableFontStyle.Value) newStyle = originalFont.Style | fontStyle.Value; else newStyle = originalFont.Style & ~fontStyle.Value; } newFont = new Font(!ssortingng.IsNullOrEmpty(familyName) ? familyName : originalFont.FontFamily.Name, emSize.HasValue ? emSize.Value : originalFont.Size, newStyle.HasValue ? newStyle.Value : originalFont.Style); return newFont; } 

Pour plus d’explications, vous pouvez aller sur: http://how-to-code-net.blogspot.ro/2014/01/how-to-make-custom-richtextbox-control.html

Je suis encore à le tester en termes de références d’object de police consommant plus de mémoire cependant

Cela devrait marcher

  if(rtbCaseContent.SelectedText.Length > 0 ) { // calculate font style FontStyle style = FontStyle.Underline; Font selectedFont = rtbCaseContent.SelectionFont; if (rtbCaseContent.SelectionFont.Bold == true) { style |= FontStyle.Bold; } if (rtbCaseContent.SelectionFont.Italic == true) { style |= FontStyle.Italic; } rtbCaseContent.SelectionFont = new Font(selectedFont,style); } 

si vous souhaitez appliquer plus de FontStyle sur le même texte, vous pouvez utiliser des opérateurs au niveau des bits | et ~ | ajoute un nouveau style et ~ supprime un style existant par exemple

 Font aFont=new Font(aPrototypeFont, anotherFont.Style | FontStyle.Bold);