在上一篇文章中,我们研究了 TextBlock 控件的核心功能:显示一个简单的字符串并在必要时对其进行包装。我们甚至使用了不同于默认颜色的另一种颜色来呈现文本,但是如果您想做的不仅仅是为 TextBlock 中的所有文本定义一种静态颜色,该怎么办?
TextBlock 控件支持内联元素。这些类似控件的小构造都继承自 Inline 类,这意味着它们可以作为较大文本的一部分内联呈现。支持的元素包括 AnchoredBlock、Bold、Hyperlink、InlineUIContainer、Italic、LineBreak、Run、Span 和 Underline。在下面的例子中,我们将看到其中的大部分。
粗体、斜体和下划线
这些可能是最简单的内联元素类型。这些名字应该告诉你很多关于它们的作用,但我们仍然会给你一个关于如何使用它们的快速示例:
<Window x:Class="WpfTutorialSamples.Basic_controls.TextBlockInlineSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TextBlockInlineSample" Height="100" Width="300">
<Grid>
<TextBlock Margin="10" TextWrapping="Wrap">
TextBlock with <Bold>bold</Bold>, <Italic>italic</Italic> and <Underline>underlined</Underline> text.
</TextBlock>
</Grid>
</Window>
与 HTML 非常相似,您只需用 Bold 标记包围文本即可获得粗体文本等。这使得在您的应用程序中创建和显示不同的文本变得非常容易。
所有这三个标签都只是 Span 元素的子类,每个标签都在 Span 元素上设置一个特定的属性以创建所需的效果。例如,Bold 标签只设置底层 Span 元素的 FontWeight 属性,Italic 元素设置 FontStyle 等等。
越线
只需在文本中插入换行符。有关我们使用 LineBreak 元素的示例,请参阅上一章。
超链接
Hyperlink 元素允许您在文本中添加链接。它以适合您当前 Windows 主题的样式呈现,通常是某种带有红色悬停效果和手鼠标光标的带下划线的蓝色文本。您可以使用 NavigateUri 属性来定义要导航到的 URL。下面是一个例子:
<Window x:Class="WpfTutorialSamples.Basic_controls.TextBlockHyperlinkSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TextBlockHyperlinkSample" Height="100" Width="300">
<Grid>
<TextBlock Margin="10" TextWrapping="Wrap">
This text has a <Hyperlink RequestNavigate="Hyperlink_RequestNavigate" NavigateUri="https://www.google.com">link</Hyperlink> in it.
</TextBlock>
</Grid>
</Window>
超链接也用于 WPF 页面内部,可用于在页面之间导航。在这种情况下,您不必像我们在示例中所做的那样专门处理 RequestNavigate 事件,但要从常规 WPF 应用程序启动外部 URL,我们需要此事件和 Process 类的一些帮助。我们订阅了 RequestNavigate 事件,它允许我们在用户默认浏览器中使用一个简单的事件处理程序启动链接的 URL,就像在代码隐藏文件中的那样:
private void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
{
System.Diagnostics.Process.Start(e.Uri.AbsoluteUri);
}
Run
Run 元素允许您使用 Span 元素的所有可用属性来设置字符串的样式,但是虽然 Span 元素可能包含其他内联元素,但 Run 元素可能只包含纯文本。这使得 Span 元素更加灵活,因此在大多数情况下是合乎逻辑的选择。
跨度
Span 元素默认没有任何特定的渲染,但允许您设置几乎任何类型的特定渲染,包括字体大小、样式和粗细、背景和前景色等。Span 元素的伟大之处在于它允许在其中包含其他内联元素,甚至可以轻松实现文本和样式的高级组合。在下面的示例中,我使用了许多 Span 元素来向您展示使用内联 Span 元素时的多种可能性:
<Window x:Class="WpfTutorialSamples.Basic_controls.TextBlockSpanSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TextBlockSpanSample" Height="100" Width="300">
<Grid>
<TextBlock Margin="10" TextWrapping="Wrap">
This <Span FontWeight="Bold">is</Span> a
<Span Background="Silver" Foreground="Maroon">TextBlock</Span>
with <Span TextDecorations="Underline">several</Span>
<Span FontStyle="Italic">Span</Span> elements,
<Span Foreground="Blue">
using a <Bold>variety</Bold> of <Italic>styles</Italic>
</Span>.
</TextBlock>
</Grid>
</Window>
因此,如果在您的情况下没有其他元素有意义,或者如果您在开始格式化文本时只想要一个空白画布,则 Span 元素是一个不错的选择。
从 C#/Code-Behind 格式化文本
如您所见,通过 XAML 格式化文本非常容易,但在某些情况下,您可能更喜欢甚至需要从 C#/Code-Behind 文件中进行格式化。这有点麻烦,但这里有一个关于如何做的例子:
<Window x:Class="WpfTutorialSamples.Basic_controls.TextBlockCodeBehindSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TextBlockCodeBehindSample" Height="100" Width="300">
<Grid></Grid>
</Window>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
namespace WpfTutorialSamples.Basic_controls
{
public partial class TextBlockCodeBehindSample : Window
{
public TextBlockCodeBehindSample()
{
InitializeComponent();
TextBlock tb = new TextBlock();
tb.TextWrapping = TextWrapping.Wrap;
tb.Margin = new Thickness(10);
tb.Inlines.Add("An example on ");
tb.Inlines.Add(new Run("the TextBlock control ") { FontWeight = FontWeights.Bold });
tb.Inlines.Add("using ");
tb.Inlines.Add(new Run("inline ") { FontStyle = FontStyles.Italic });
tb.Inlines.Add(new Run("text formatting ") { Foreground = Brushes.Blue });
tb.Inlines.Add("from ");
tb.Inlines.Add(new Run("Code-Behind") { TextDecorations = TextDecorations.Underline });
tb.Inlines.Add(".");
this.Content = tb;
}
}
}
有这种可能性真是太好了,在某些情况下可能有必要这样做。