Quelle est la meilleure façon de construire un FrameworkElement qui a le texte de balisage gras et en italique?

StackOverflow https://stackoverflow.com/questions/2280924

  •  21-09-2019
  •  | 
  •  

Question

Y at-il façon plus élégante de faire ce qui suit?

Fondamentalement, je besoin d'un moyen facile de programatically construire un WrapPanel (ou autre FrameworkElement) que:

  • enveloppements correctement
  • permet quelques mots d'avoir gras texte
  • permet quelques mots d'avoir italique texte
  • permet à d'autres Mise en forme , par exemple couleur, fond
  • idéal serait une méthode qui convertit par exemple « This is <b>bold</b> and this is <i>italic</i> text. » dans un FrameworkElement approprié je peux par exemple ajouter à un StackPanel et l'afficher.

Code:

using System.Windows;
using System.Windows.Controls;

namespace TestAddTextBlock2343
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            WrapPanel wp = new WrapPanel();

            wp.AddTextBlock("This is a sentence with ");

            {
                TextBlock tb = wp.AddTextBlockAndReturn("bold text");
                tb.FontWeight = FontWeights.Bold;
            }

            wp.AddTextBlock(" and ");

            {
                TextBlock tb = wp.AddTextBlockAndReturn("italic text");
                tb.FontStyle = FontStyles.Italic;
            }

            wp.AddTextBlock(" in it.");
        }
    }

    public static class XamlHelpers
    {
        public static TextBlock AddTextBlockAndReturn(this WrapPanel wp, string text)
        {
            TextBlock tb = new TextBlock();
            tb.Text = text;
            wp.Children.Add(tb);
            return tb;
        }

        public static void AddTextBlock(this WrapPanel wp, string text)
        {
            TextBlock tb = wp.AddTextBlockAndReturn(text);
        }
    }
}
Était-ce utile?

La solution

Edit: j'ai découvert dans une autre réponse que le TextBlock dispose également d'une collection de Inlines auquel on peut ajouter Runs. réponse de Anvaka utilise ingénieusement une propriété jointe en une sorte de convertisseur.


Ce que je pense conviendra à votre situation est un FlowDocumentScrollViewer et un FlowDocument. Je décris la création manuelle d'un par un IValueConverter un peu ici .

Vous utiliserez probablement des fonctions d'aide similaires que vous avez montré dans votre exemple, mais le FlowDocument est déjà un peu comme HTML et gérerez l'emballage sans effort.

Vous ajoutez Paragraphs au FlowDocument, vous ajoutez Runs au Paragraph, et chaque Run dérive de TextElement il a beaucoup des mêmes propriétés que TextBlocks font.

FlowDocument doc = new FlowDocument();
Paragraph par = new Paragraph();
doc.Blocks.Add( par );

Run r;
r = new Run( "This is " );
par.Inlines.Add( r );

r = new Run( "bold" );
r.FontWeight = FontWeights.Bold;
par.Inlines.Add( r );

r = new Run( " and this is " );
par.Inlines.Add( r );

r = new Run( "italic" );
r.FontStyle = FontStyles.Italic;
par.Inlines.Add( r );

r = new Run( " text." );
par.Inlines.Add( r );

En outre, si les sous-chaînes de formatage vont rester limitées à des balises italique / gras ou un autre balisage extrêmement simple, l'utilisation de Regex.Split() pourrait être la meilleure façon de déterminer les Runs séparés à partir d'une seule chaîne. Il vous permet de diviser une chaîne en plusieurs chaînes mais gardez votre « délimiteurs ».

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top