Каков самый простой способ создать FrameworkElement с полужирным и курсивным текстом разметки?
Вопрос
Есть ли более элегантный способ сделать следующее?
В принципе мне нужен простой способ программно построить WrapPanel
(или другой FrameworkElement), который:
- обертывания правильно
- позволяет некоторым словам иметь смелый текст
- позволяет некоторым словам иметь курсив текст
- позволяет другим форматирование, напримерцвет, фон
- идеальным был бы какой-то метод, который преобразует, например."
This is <b>bold</b> and this is <i>italic</i> text.
" в соответствующий FrameworkElement, чтобы я мог, например. добавьте его в StackPanel и отобразить его.
Код:
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);
}
}
}
Решение
Редактировать:В другом ответе я обнаружил, что TextBlock
также имеет Inlines
коллекция, к которой можно добавить Run
с. Ответ Анваки изобретательно использует присоединенное свойство как своего рода преобразователь.
Я думаю, что в вашей ситуации подойдет FlowDocumentScrollViewer
и FlowDocument
.Я описываю ручное создание одного через IValueConverter
немного здесь.
Скорее всего, вы будете использовать аналогичные вспомогательные функции, как показано в вашем примере, но FlowDocument
уже очень похож на HTML и легко справляется с переносом.
Вы добавляете Paragraph
s к FlowDocument
, вы добавляете Run
s к Paragraph
, и каждый Run
происходит от TextElement
поэтому он имеет много тех же свойств, что и TextBlock
да.
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 );
Кроме того, если подстроки форматирования будут ограничены тегами, выделенными жирным шрифтом/курсивом, или какой-либо другой чрезвычайно простой разметкой, используйте Regex.Split()
возможно, это самый простой способ определить отдельные Run
s из одной строки.Это позволяет вам разделить строку на несколько строк, но сохранить «разделители».