Какой самый простой способ создать 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);
        }
    }
}

1 ответ

Решение

Изменить: я обнаружил в другом ответе, что TextBlock также имеет Inlines коллекция, в которую можно добавить Runs. Ответ Анваки изобретательно использует прикрепленное свойство как своего рода конвертер.


То, что я думаю, подойдет вашей ситуации FlowDocumentScrollViewer и FlowDocument, Я описываю ручное создание одного через IValueConverter немного здесь

Скорее всего, вы будете использовать те же вспомогательные функции, что и в своем примере, но FlowDocument уже очень похож на HTML и легко справится с переносом.

Вы добавляете Paragraphс FlowDocument, вы добавляете Runс 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с одной строки. Это позволяет вам разбить строку на несколько строк, но оставить "разделители".

Другие вопросы по тегам