Каков самый простой способ создать FrameworkElement с полужирным и курсивным текстом разметки?

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

  •  21-09-2019
  •  | 
  •  

Вопрос

Есть ли более элегантный способ сделать следующее?

В принципе мне нужен простой способ программно построить 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 и легко справляется с переносом.

Вы добавляете Paragraphs к FlowDocument, вы добавляете Runs к 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() возможно, это самый простой способ определить отдельные Runs из одной строки.Это позволяет вам разделить строку на несколько строк, но сохранить «разделители».

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top