背水一战 Windows 10 (27) - 控件(文本类): TextBlock
背水一战 Windows 10 (27) - 控件(文本类): TextBlock
作者:webabcd
介绍
背水一战 Windows 10 之 控件(文本类)
- TextBlock
示例
1、TextBlock 的示例 1
Controls/TextControl/TextBlockDemo1.xaml
<Page x:Class="Windows10.Controls.TextControl.TextBlockDemo1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:Windows10.Controls.TextControl" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="Transparent"> <StackPanel Margin="10 0 10 10"> <!-- TextBlock 的常用属性 Text - 显示的文本,如果需要显示引号等特殊字符需要使用相应的 HTML 编码 Foreground - 文本颜色 FontFamily - 首选字体,多个用“,”分隔,找不到第 1 个就用第 2 个,找不到第 2 个就用第 3 个,以此类推 FontSize - 字号大小(单位:像素) FontWeight - 字体粗细(FontWeights 实体类),默认值是 Normal FontStyle - 字体样式(FontStyle 枚举),默认值是 Normal Italic - 使用字体自带的斜体 Oblique - 通过程序让正常字体倾斜(对于自身不带斜体的字体可以使用此值让字体倾斜) FontStretch - 字体的拉伸值(FontStretch 枚举),默认值是 Normal(大部分字体都不支持这个属性) Padding - Padding IsTextScaleFactorEnabled - 是否启用文本自动放大功能(默认值是 true) 在“设置”->“轻松使用”中可以调整文本缩放大小,IsTextScaleFactorEnabled 就是用于决定 TextBlock 显示的文本是否跟着这个设置走 --> <TextBlock Text="i am a "TextBlock"" Margin="5" Foreground="Blue" FontFamily="微软雅黑" FontSize="24" FontWeight="Bold" FontStyle="Italic" FontStretch="Normal" Padding="5" /> <!-- TextAlignment - 文本的水平对齐方式 Center, Left(默认值), Right, Justify(两端对齐) --> <TextBlock Text="i am a "TextBlock"" Margin="5" TextAlignment="Justify" /> <!-- TextWrapping - 换行方式 NoWrap - 不换行 Wrap - 换行,必要时可截断单词 WrapWholeWords - 换行,但是绝不截断单词,即使单词可能会显示不全 --> <TextBlock Width="100" HorizontalAlignment="Left" Text="abcdefghijklmnopq www" Margin="5" TextWrapping="NoWrap" /> <TextBlock Width="100" HorizontalAlignment="Left" Text="abcdefghijklmnopq www" Margin="5" TextWrapping="Wrap" /> <TextBlock Width="100" HorizontalAlignment="Left" Text="abcdefghijklmnopq www" Margin="5" TextWrapping="WrapWholeWords" /> <!-- TextTrimming - 内容溢出时的修整方式 None - 不修整文本 Clip - 在像素级别修整文本 WordEllipsis - 在单词级别修整文本,同时用省略号代替剩余文本 CharacterEllipsis - 在字符级别修整文本,同时用省略号代替剩余文本 --> <TextBlock Width="100" HorizontalAlignment="Left" Text="abcdefghi jklmnopqrstuvwxyz" Margin="5" TextTrimming="None"/> <TextBlock Width="100" HorizontalAlignment="Left" Text="abcdefghi jklmnopqrstuvwxyz" Margin="5" TextTrimming="Clip"/> <TextBlock Width="100" HorizontalAlignment="Left" Text="abcdefghi jklmnopqrstuvwxyz" Margin="5" TextTrimming="WordEllipsis"/> <TextBlock Width="100" HorizontalAlignment="Left" Text="abcdefghi jklmnopqrstuvwxyz" Margin="5" TextTrimming="CharacterEllipsis"/> <!-- MaxLines - 用于指定文本最大的显示行数 --> <TextBlock MaxLines="3" Margin="5"> <TextBlock.Inlines> <Run>111111</Run> <LineBreak /> <Run>222222</Run> <LineBreak /> <Run>333333</Run> <LineBreak /> <Run>444444</Run> <LineBreak /> <Run>555555</Run> </TextBlock.Inlines> </TextBlock> <!-- CharacterSpacing - 用于设置字符间距 具体字符间隔像素计算公式如下:字体大小 * CharacterSpacing值 / 1000 = 字符间距像素值 LineHeight - 行高 LineStackingStrategy - 控制行高的策略 MaxHeight - 每行的行高以 LineHeight 值和每行的自然行高中的最大值为准。默认值 BlockLineHeight - 每行的行高以 LineHeight 值为准,以字符区域为参考 BaselineToBaseline - 每行的行高以 LineHeight 值为准,以基线为参考(什么是基线:英文字符的基线基本相当于单词本4条线中的第3条线) Inlines - 内联元素的集合。包括 span, bold, italic, underline 等,但是 InlineUIContainer 不可用,其需要在 RichTextBlock 中使用 --> <TextBlock Margin="5" CharacterSpacing="100" LineStackingStrategy="MaxHeight" LineHeight="50"> <TextBlock.Inlines> <Run Foreground="Red">Run</Run> <Span Foreground="Blue">Span</Span> <LineBreak /> <Bold>Bold</Bold> <Italic>Italic</Italic> <Underline>Underline</Underline> </TextBlock.Inlines> </TextBlock> <!-- TextLineBounds - 行框的绘制方式 Full - 正常,默认值 TrimToCapHeight - 行框顶部和大写字体的顶部一致 TrimToBaseline - 行框底部与文本基线一致(什么是基线:英文字符的基线基本相当于单词本4条线中的第3条线) Tight - 行框顶部和大写字体的顶部一致,行框底部与文本基线一致 --> <Grid Background="Red" Margin="5"> <TextBlock Text="Aj" FontSize="24" TextLineBounds="Full" /> </Grid> <Grid Background="Red" Margin="5"> <TextBlock Text="Aj" FontSize="24" TextLineBounds="TrimToCapHeight" /> </Grid> <Grid Background="Red" Margin="5"> <TextBlock Text="Aj" FontSize="24" TextLineBounds="TrimToBaseline" /> </Grid> <Grid Background="Red" Margin="5"> <TextBlock Text="Aj" FontSize="24" TextLineBounds="Tight" /> </Grid> <!-- 在 xaml 中使用特殊字符,如下打印的内容为“<>&"” --> <TextBlock Text="<>&"" Margin="5" /> <!-- 通过 ASCII 编码显示指定的字符 = 十进制,其对应的是“=” = 十六进制,其对应的是“=” & 十进制,其对应的是“&” & 十六进制,其对应的是“&” --> <TextBlock Text="==&&" Margin="5" /> </StackPanel> </Grid> </Page>
Controls/TextControl/TextBlockDemo1.xaml.cs
/* * TextBlock - 文本显示框(继承自 FrameworkElement, 请参见 /Controls/BaseControl/FrameworkElementDemo/) */ using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; namespace Windows10.Controls.TextControl { public sealed partial class TextBlockDemo1 : Page { public TextBlockDemo1() { this.InitializeComponent(); } } }
2、TextBlock 的示例 2
Controls/TextControl/TextBlockDemo2.xaml
<Page x:Class="Windows10.Controls.TextControl.TextBlockDemo2" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:Windows10.Controls.TextControl" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="Transparent"> <StackPanel Margin="10 0 10 10"> <!-- IsTextSelectionEnabled - 文本是否可以被选中 SelectionHighlightColor - 选中文本的颜色 --> <TextBlock Name="textBlock1" Margin="5" IsTextSelectionEnabled="True" SelectionHighlightColor="Red"> <TextBlock.Inlines> <Run>abcdefg</Run> <LineBreak /> <Run>hijklmn</Run> <LineBreak /> <Run>opqrst</Run> </TextBlock.Inlines> </TextBlock> <!--显示 textBlock1 中被用户选中的文本--> <TextBlock Name="lblMsg1" Margin="5" /> <TextBlock Name="textBlock2" Margin="5" IsTextSelectionEnabled="True" SelectionHighlightColor="Red"> <Run>abcdefghijklmn</Run> <LineBreak /> <Run>opqrstuvwxyz</Run> </TextBlock> <TextBlock Name="lblMsg2" Margin="5" /> <Grid Background="Red" Margin="5"> <TextBlock Name="textBlock3" Text="abcdefghijklmnopqrstuvwxyz" FontSize="24" /> <!--用于绘制基线--> <Line Name="line" Stroke="Blue" StrokeThickness="1" X1="0" X2="300" /> </Grid> <TextBlock Name="lblMsg3" Margin="5" /> <!--用于显示 Segoe UI Emoji 字符--> <TextBlock Name="textBlock4" Margin="5" FontSize="24" TextWrapping="Wrap" /> <!--用于演示如何计算 TextBlock 的实际宽度和实际高度--> <Grid Name="grid" Margin="5"> <Grid.ColumnDefinitions> <ColumnDefinition x:Name="gridColumn1" Width="Auto" /> <ColumnDefinition x:Name="gridColumn2" Width="*" /> </Grid.ColumnDefinitions> <TextBlock Name="textBlock5" FontSize="24"> <Run>abc</Run> <LineBreak /> <Run>xyz</Run> </TextBlock> </Grid> <TextBlock Name="lblMsg5" Margin="5" /> </StackPanel> </Grid> </Page>
Controls/TextControl/TextBlockDemo2.xaml.cs
/* * TextBlock - 文本显示框(继承自 FrameworkElement, 请参见 /Controls/BaseControl/FrameworkElementDemo/) * SelectedText - 获取选中的文本内容 * SelectionChanged - 选中的文本内容发生变化后触发的事件 * ContentStart - 开头内容的 TextPointer 对象 * ContentEnd - 结尾内容的 TextPointer 对象 * Focus(FocusState value) - 获取焦点 * SelectAll() - 选中全部内容(先要获取焦点后,才能做这个操作) * Select(TextPointer start, TextPointer end) - 选中指定范围的内容(先要获取焦点后,才能做这个操作) * SelectionStart - 选中内容的起始位置(TextPointer 对象) * SelectionEnd - 选中内容的结束位置(TextPointer 对象) * BaselineOffset - 获取基线的位置(什么是基线:英文字符的基线基本相当于单词本4条线中的第3条线) * IsColorFontEnabled - 是否以彩色方式显示 Segoe UI Emoji 之类的字符(默认值是 true) * * * TextPointer - 文本框中的指针对象 * Offset - 指针的位置 * LogicalDirection - 指针的逻辑方向 * Backward - 向后,即从右到左(比如,如果插入字符的话,就会在指针位置的左边插入) * Forward - 向前,即从左到右(比如,如果插入字符的话,就会在指针位置的右边插入) * Rect GetCharacterRect(LogicalDirection direction) - 返回当前指针的矩形框 * TextPointer GetPositionAtOffset(offset, LogicalDirection direction) - 将指针位置偏移指定的距离(正代表向右偏移,负代表向左偏移) */ using System; using System.Text; using Windows.Foundation; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Documents; namespace Windows10.Controls.TextControl { public sealed partial class TextBlockDemo2 : Page { public TextBlockDemo2() { this.InitializeComponent(); this.Loaded += TextBlockDemo2_Loaded; } private void TextBlockDemo2_Loaded(object sender, RoutedEventArgs e) { textBlock1.SelectionChanged += (x, y) => { // 显示用户选中的文本内容 lblMsg1.Text = textBlock1.SelectedText; }; textBlock1.ContextMenuOpening += (x, y) => { // 触发条件:触摸屏长按或鼠标右键 }; // 获取焦点 textBlock2.Focus(FocusState.Programmatic); TextPointer start = textBlock2.ContentStart; TextPointer end = textBlock2.ContentEnd; // textBlock2 的 Text 的内容一共有 26 个字符,但是这里的指针位置 offset 是从 0 到 34,一共 35 个指针位置 // <LineBreak /> 占 4 个指针位置,开头占 2 个指针位置,结尾占 2 个指针位置。剩下的就比较好理解了,就是 26 个字符拥有 27 个指针位置 lblMsg2.Text = $"ContentStart.Offset: {start.Offset}, ContentEnd.Offset: {end.Offset}"; lblMsg2.Text += Environment.NewLine; // 从左到右偏移 3 个位置,即指针位置在第 1 个字符的右边 start = start.GetPositionAtOffset(3, LogicalDirection.Backward); // 从右到左偏移 3 个位置,即指针位置在最后一个字符的左边 end = end.GetPositionAtOffset(-3, LogicalDirection.Forward); textBlock2.Select(start, end); // SelectAll() - 选中全部 lblMsg2.Text += $"SelectionStart.Offset: {textBlock2.SelectionStart.Offset}, SelectionEnd.Offset: {textBlock2.SelectionEnd.Offset}"; // 获取基线的位置,并通过 Line 绘制基线 lblMsg3.Text += $"BaselineOffset: {textBlock3.BaselineOffset}"; line.Y1 = textBlock3.BaselineOffset; line.Y2 = textBlock3.BaselineOffset; // 显示 Segoe UI Emoji 字符 StringBuilder strContect = new StringBuilder(); for (int code = 0x1F600; code < 0x1F6C6; code++) { strContect.Append(char.ConvertFromUtf32(code)); } // 是否以彩色方式显示 Segoe UI Emoji 之类的字符(默认值是 true) textBlock4.IsColorFontEnabled = true; textBlock4.Text = strContect.ToString(); // 通过封一层 Grid 的方式计算 TextBlock 的实际宽度和实际高度 lblMsg5.Text = $"textBlock5 的实际高度: {grid.ActualHeight}"; lblMsg5.Text += Environment.NewLine; lblMsg5.Text += $"textBlock5 的实际宽度: {gridColumn1.ActualWidth}"; lblMsg5.Text += Environment.NewLine; // 通过 TextPointer 的方式计算 TextBlock 的实际高度 TextPointer last = textBlock5.ContentEnd; last = last.GetPositionAtOffset(-3, LogicalDirection.Forward); Rect rectLast = last.GetCharacterRect(LogicalDirection.Forward); lblMsg5.Text += $"textBlock5 的实际高度: {rectLast.Bottom}"; lblMsg5.Text += Environment.NewLine; // 通过 TextPointer 的方式计算 TextBlock 的实际宽度 int count = textBlock5.ContentEnd.Offset - textBlock5.ContentStart.Offset; double width = 0; for (int i = 0; i < count; i++) { TextPointer current = textBlock5.ContentStart.GetPositionAtOffset(i, LogicalDirection.Backward); width = Math.Max(width, current.GetCharacterRect(LogicalDirection.Backward).Right); } lblMsg5.Text += $"textBlock5 的实际宽度: {width}"; } } }
3、使用自定义字体, 使用 Unicode 编码
Controls/TextControl/Tips.xaml
<Page x:Class="Windows10.Controls.TextControl.Tips" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:Windows10.Controls.TextControl" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="Transparent"> <StackPanel Margin="10 0 10 10"> <!-- 文本类控件使用自定义字体 1、将字体文件复制到项目中 2、通过 FontFamily 指定字体文件的路径,在路径后加“#”并在其后写上字体名称(通过“Windows 字体查看器”可以查看字体文件的字体名称) --> <TextBlock Text="逐浪大雪钢笔体" FontSize="36" Margin="5" FontFamily="/Controls/TextControl/MyFont.otf#逐浪大雪钢笔体"> </TextBlock> <!-- 文本类控件使用 Unicode 编码 1、无法在 xaml 中使用 \u(在 code-behind 中可以) 2、通过 � 的方式来显示 Unicode 字符(注:unicode 的 0 - 127 与 ascii 一样) --> <TextBlock Text=""123"
123" FontSize="36" Margin="5" /> </StackPanel> </Grid> </Page>
Controls/TextControl/Tips.xaml.cs
/* * 演示文本类控件如何使用自定义字体,以及使用 Unicode 编码 */ using Windows.UI.Xaml.Controls; namespace Windows10.Controls.TextControl { public sealed partial class Tips : Page { public Tips() { this.InitializeComponent(); } } }
OK
[源码下载]