构建具有粗体和斜体标记文本的 FrameworkElement 最简单的方法是什么?

发布于 2024-08-21 20:43:28 字数 1632 浏览 5 评论 0原文

有没有更优雅的方法来执行以下操作?

基本上,我需要一种简单的方法来以编程方式构建一个WrapPanel(或其他FrameworkElement):

  • 正确换行
  • 允许某些单词具有粗体文本
  • 允许某些单词具有斜体文本
  • 允许其他格式,例如颜色,理想的背景
  • 是将“This is bold and this is italic 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);
        }
    }
}

Is there any more elegant way to do the following?

Basically I need an easy way to programatically build a WrapPanel (or other FrameworkElement) that:

  • wraps correctly
  • allows some words to have bold text
  • allows some words to have italic text
  • allows other formatting, e.g. color, background
  • ideal would be some method that converts e.g. "This is <b>bold</b> and this is <i>italic</i> text." into an appropriate FrameworkElement so I can e.g. add it to a StackPanel and display it.

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);
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

绝不放开 2024-08-28 20:43:28

编辑:我在另一个答案中发现 TextBlock 也有一个 Inlines 集合,可以向其中添加 RunAnvaka的答案巧妙地使用附加属性作为一种转换器。


我认为适合您情况的是 FlowDocumentScrollViewerFlowDocument。我描述了通过 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 的最简单方法 来自单个字符串。它允许您将一个字符串拆分为多个字符串,但保留“分隔符”。

Edit: I discovered in a different answer that the TextBlock also has an Inlines collection to which one can add Runs. Anvaka's answer ingeniously uses an attached property as a sort of converter.


What I think will suit your situation is a FlowDocumentScrollViewer and a FlowDocument. I describe manual creation of one through an IValueConverter a little bit here.

You'll likely use similar helper functions as you've shown in your example, but the FlowDocument is already much like HTML and will handle wrapping effortlessly.

You add Paragraphs to the FlowDocument, you add Runs to the Paragraph, and each Run derives from TextElement so it has a lot of the same properties that TextBlocks do.

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 );

Also, if the formatting substrings are going to remain restricted to bold/italic tags or some other extremely simple markup, use of Regex.Split() might be the easiest way to determine the separate Runs from a single string. It allows you to split a string into multiple strings but keep your "delimiters".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文