Quelle est la meilleure façon de construire un FrameworkElement qui a le texte de balisage gras et en italique?
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);
}
}
}
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 Run
s. 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 Paragraph
s au FlowDocument
, vous ajoutez Run
s au Paragraph
, et chaque Run
dérive de TextElement
il a beaucoup des mêmes propriétés que TextBlock
s 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 Run
s 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 ».