支持 HTML 的 WPF TextBlock






4.36/5 (9投票s)
本文描述了 HtmlTextBlock,它是一个 WPF TextBlock,可以解析有限的 HTML 标签并显示它们。

引言
本文描述了 HtmlTextBlock
,它是一个 WPF TextBlock
,可以解析有限的 HTML 标签并显示它们。
背景
我正在开发一个自定义进度对话框,其中包含标题、消息、进度和一些操作按钮。
为了让它看起来更好,我希望消息支持一些文本格式,并且希望在运行时可以更改它,但使用 TextBlock
似乎是不可能的。

然后我 Google 了如何在 WPF 中使用 HTML,但大多数解决方案告诉我使用 WebBrowser,这对于我的目的来说有点过头了。
然后我想起了一个几年前编写的废弃项目(主要是因为我转向了 WPF),它试图在 .NET 2 中重新创建 FlowDocument
,并加载 HTML 文档(我的主要目的,该组件名为 QzMiniHtml2
)。
令人惊讶的是,经过很少的修改(主要是使用 import),这个 .NET 2 项目可以很好地与 WPF 配合使用,就像您在上面看到的那样。
因此,原始项目也包含在内。
如何使用?
该控件类似于 TextBlock
,只是您设置 HTML 属性而不是 Text
。
请记住使用 [ ]
方括号代替 < >
。
<Window x:Class="HtmlTextBlockTestProj.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:uc="http://www.quickzip.org/UserControls"
Title="HtmlTextBlockTest" Height="250" Width="450">
<DockPanel>
<uc:HtmlTextBlock Html="{Binding Text, ElementName=tb}"
DockPanel.Dock="Top" Loaded="HtmlTextBlock_Loaded" />
<TextBlock Text="[b] [i] [u] [a href=xx] [br] supported."
DockPanel.Dock="Bottom" />
<TextBox TextWrapping="Wrap" AcceptsReturn="True"
VerticalScrollBarVisibility="Visible"
x:Name="tb"
Text="The [i][u]quick brown fox[/i][/u] jumps over the [b]lazy dog[/b]" />
</DockPanel>
</Window>
它是如何工作的?
该组件实际上包含一个 HTML 解析引擎,它将 HTML string
转换为 WPF 的粗体、斜体、下划线、超链接、行中断内联(未来可以添加更多,您可以轻松地自己完成,请参见下文)。
转换部分很简单。
1) private Inline UpdateElement(HtmlTag aTag)
2) {
3) Inline retVal = null;
4) switch (aTag.Name)
5) {
6) case "text" :
7) retVal = new Run(aTag["value"]);
8) if (currentState.Bold) retVal = new Bold(retVal);
9) if (currentState.Italic) retVal = new Italic(retVal);
0) if (currentState.Underline) retVal = new Underline(retVal);
A) break;
B) case "br" :
C) retVal = new LineBreak();
D) break;
E) }
F) if (currentState.HyperLink != null && currentState.HyperLink != "")
G) {
H) Hyperlink link = new Hyperlink(retVal);
I) link.NavigateUri = new Uri(currentState.HyperLink);
J) retVal = link;
K) }
L) return retVal;
M) }
首先,请注意
- 输入 (
aTag
) 是一个文本或行中断 (br
),如果标签是文本,Tag["value"]
是它包含的文本。
粗体、斜体等也可以由HtmlTag
表示,但它们不会在这里执行。 CurrentState
包含影响TextTag
等样式的状态。
所以如果标签是文本 (第 6 行)
- 它将生成一个
Run
(可以包含格式化或未格式化的文本,并且在本例中未格式化)(第 7 行) - 如果是粗体、斜体和下划线,它将构建它们,并使用最后一个内联 (抽象类,Run、Bold 等继承自它),因此它包含该属性。
当内联返回时 (第 L 行)
- 它将被添加到您的
HtmlTextBlock.Inlines
集合中。
历史
- 09-02-08 初始版本