如何在一条基线上对齐 TextBlock 和 TextBox 文本
How to align TextBlock and TextBox text on one baseline
我正在尝试为一组带有标签的控件找出一个好的布局。例如,如果我在文本框的左侧有一个标签,则标签的基线和文本框不在同一垂直位置。通常的解决方法是将两个控件垂直居中,但如果您有多行文本框控件,这看起来不太好。
我得到了一些组合。
我希望相关面板能够提供对齐基线的选项,就像 android 相关布局面板一样。不幸的是它没有。
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<RelativePanel>
<TextBlock Text="Name:" Name="t1"></TextBlock>
<TextBox Text="Content" RelativePanel.RightOf="t1" ></TextBox>
</RelativePanel>
</Grid>
网格也无济于事。
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{x:Bind Label}" Style="{ThemeResource BaseTextBlockStyle}"/>
<TextBox Grid.Column="1" Text="Content" HorizontalAlignment="Stretch"></TextBox>
</Grid>
</Grid>
显然水平堆栈面板也没有什么魔力。
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel Orientation="Horizontal">
<TextBlock Grid.Column="0" Text="{x:Bind Label}" Style="{ThemeResource BaseTextBlockStyle}"/>
<TextBox Grid.Column="1" Text="Content" VerticalAlignment="Top"></TextBox>
</StackPanel>
</Grid>
垂直堆栈面板可以避免这个问题,但我更喜欢控件左侧的标签。
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel Orientation="Vertical">
<TextBlock Grid.Column="0" Text="{x:Bind Label}" Style="{ThemeResource BaseTextBlockStyle}"/>
<TextBox Grid.Column="1" Text="Content" ></TextBox>
</StackPanel>
</Grid>
您对如何对齐基线有任何想法吗?这/或者对于许多输入控件和标签来说可能是一个不错的布局想法?
我快速浏览了文档,我认为 UWP 中没有与 Android 的基线对齐等效的东西。文本控件不会暴露其基线的位置以供面板使用,因为它高度依赖于控件的模板(可以完全更改,不像 Android 中视图的视觉外观是有点像 hard-coded).
无论如何,通过检查文本框的可视化树,我发现最里面的 TextBoxView(实际显示和处理 TextBox 控件的文本输入的控件)以与 TextBlock 相同的方式呈现文本(意思是填充等是相同的)。因此,只要我们可以将 TextBlock 的顶部边缘与 TextBoxView 对齐,那么两个控件的文本就会处于相同的垂直位置。当然,两个控件的字体和字体大小需要相同(默认情况下)。
TextBoxView 被其 parent ScrollContentPresenter 向下推 3px(有效像素),文本框边框被向下推 2px。因此,您只需向 TextBlock 添加 5px 的上边距,两个控件的文本就会对齐。
仅供参考,这是基于我正在使用的 SDK 版本 14393 提供的默认文本框模板。 Microsoft 可以使用新的 SDK 版本更改这些样式。
查看 Android 文档,视图 class 有一个方法 getBaseline;在 UWP 中,UIElement(或 FrameworkElement)没有这样的等价物。搜索可视化树并尝试确定您看到的第一个文本元素的基线可能并非在所有情况下都有效(某些元素具有多个文本元素)。
如果你要有很多这些 left-labelled-elements,一些建议:
- 创建一个带有正确位置的标签和文本框的用户控件。这样一来,您只需在代码中的一个地方硬编码边距,如果您需要更改它,则只需更改一段代码。
- TextBox 控件(与许多其他控件一样)有一个 Header 属性,您可以在其中指定将立即显示在文本框上方的文本。您可以更改模板,使 header 位于文本框的左侧。
似乎推荐的方法是使用Header 属性 并将标签放在最上面。大多数 UWP 应用程序都这样做(在 Groove 中编辑歌曲信息时,Edge 的设置面板等)。这可能是因为在移动设备上显示时,没有太多横向 space.
实现您想要的效果的最简单方法是不创建 TextBlock
和 TextBox
,而是简单地创建两个 TextBox
元素以及您在最佳。然后将以下样式应用于 TextBox
元素,该元素应仅显示标签以使其看起来像 TextBlock
:
<Style x:Key="TransparentTextBoxStyle" TargetType="TextBox">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="IsReadOnly" Value="True" />
<Setter Property="IsTapEnabled" Value="False" />
<Setter Property="IsTabStop" Value="False" />
</Style>
我 认为 设置 IsReadOnly
、IsTapEnabled
和 IsTabStop
应该足以禁用所有潜在的交互(只是做了一个快速测试) , 但为了确保您也可以简单地将 IsEnabled
设置为 false 并将模板修改为看起来与启用它相同的样子(您可以通过打开 Document Outline 获得 VS2015 中的默认模板 window(如果看不到,可以在查看 > 其他windows) 打开可视化树找到您的项目,然后右键单击,编辑模板 和编辑副本...)。
我正在尝试为一组带有标签的控件找出一个好的布局。例如,如果我在文本框的左侧有一个标签,则标签的基线和文本框不在同一垂直位置。通常的解决方法是将两个控件垂直居中,但如果您有多行文本框控件,这看起来不太好。
我得到了一些组合。
我希望相关面板能够提供对齐基线的选项,就像 android 相关布局面板一样。不幸的是它没有。
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<RelativePanel>
<TextBlock Text="Name:" Name="t1"></TextBlock>
<TextBox Text="Content" RelativePanel.RightOf="t1" ></TextBox>
</RelativePanel>
</Grid>
网格也无济于事。
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{x:Bind Label}" Style="{ThemeResource BaseTextBlockStyle}"/>
<TextBox Grid.Column="1" Text="Content" HorizontalAlignment="Stretch"></TextBox>
</Grid>
</Grid>
显然水平堆栈面板也没有什么魔力。
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel Orientation="Horizontal">
<TextBlock Grid.Column="0" Text="{x:Bind Label}" Style="{ThemeResource BaseTextBlockStyle}"/>
<TextBox Grid.Column="1" Text="Content" VerticalAlignment="Top"></TextBox>
</StackPanel>
</Grid>
垂直堆栈面板可以避免这个问题,但我更喜欢控件左侧的标签。
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel Orientation="Vertical">
<TextBlock Grid.Column="0" Text="{x:Bind Label}" Style="{ThemeResource BaseTextBlockStyle}"/>
<TextBox Grid.Column="1" Text="Content" ></TextBox>
</StackPanel>
</Grid>
您对如何对齐基线有任何想法吗?这/或者对于许多输入控件和标签来说可能是一个不错的布局想法?
我快速浏览了文档,我认为 UWP 中没有与 Android 的基线对齐等效的东西。文本控件不会暴露其基线的位置以供面板使用,因为它高度依赖于控件的模板(可以完全更改,不像 Android 中视图的视觉外观是有点像 hard-coded).
无论如何,通过检查文本框的可视化树,我发现最里面的 TextBoxView(实际显示和处理 TextBox 控件的文本输入的控件)以与 TextBlock 相同的方式呈现文本(意思是填充等是相同的)。因此,只要我们可以将 TextBlock 的顶部边缘与 TextBoxView 对齐,那么两个控件的文本就会处于相同的垂直位置。当然,两个控件的字体和字体大小需要相同(默认情况下)。
TextBoxView 被其 parent ScrollContentPresenter 向下推 3px(有效像素),文本框边框被向下推 2px。因此,您只需向 TextBlock 添加 5px 的上边距,两个控件的文本就会对齐。
仅供参考,这是基于我正在使用的 SDK 版本 14393 提供的默认文本框模板。 Microsoft 可以使用新的 SDK 版本更改这些样式。
查看 Android 文档,视图 class 有一个方法 getBaseline;在 UWP 中,UIElement(或 FrameworkElement)没有这样的等价物。搜索可视化树并尝试确定您看到的第一个文本元素的基线可能并非在所有情况下都有效(某些元素具有多个文本元素)。
如果你要有很多这些 left-labelled-elements,一些建议:
- 创建一个带有正确位置的标签和文本框的用户控件。这样一来,您只需在代码中的一个地方硬编码边距,如果您需要更改它,则只需更改一段代码。
- TextBox 控件(与许多其他控件一样)有一个 Header 属性,您可以在其中指定将立即显示在文本框上方的文本。您可以更改模板,使 header 位于文本框的左侧。
似乎推荐的方法是使用Header 属性 并将标签放在最上面。大多数 UWP 应用程序都这样做(在 Groove 中编辑歌曲信息时,Edge 的设置面板等)。这可能是因为在移动设备上显示时,没有太多横向 space.
实现您想要的效果的最简单方法是不创建 TextBlock
和 TextBox
,而是简单地创建两个 TextBox
元素以及您在最佳。然后将以下样式应用于 TextBox
元素,该元素应仅显示标签以使其看起来像 TextBlock
:
<Style x:Key="TransparentTextBoxStyle" TargetType="TextBox">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="IsReadOnly" Value="True" />
<Setter Property="IsTapEnabled" Value="False" />
<Setter Property="IsTabStop" Value="False" />
</Style>
我 认为 设置 IsReadOnly
、IsTapEnabled
和 IsTabStop
应该足以禁用所有潜在的交互(只是做了一个快速测试) , 但为了确保您也可以简单地将 IsEnabled
设置为 false 并将模板修改为看起来与启用它相同的样子(您可以通过打开 Document Outline 获得 VS2015 中的默认模板 window(如果看不到,可以在查看 > 其他windows) 打开可视化树找到您的项目,然后右键单击,编辑模板 和编辑副本...)。