如何在一个基线上对齐 TextBlock 和 TextBox 文本

Die*_*ner 6 layout uwp uwp-xaml

我正在尝试为一组带有标签的控件找出一个不错的布局。例如,如果我在文本框左侧有一个标签,则标签和文本框的基线不在同一垂直位置。通常的解决方法是将两个控件垂直居中,但如果您有多行文本框控件,这看起来不太好。

我得到了几个组合。

我希望相对面板能够提供对齐基线的选项,就像它与 android 相对布局面板一样。不幸的是它没有。

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
  <RelativePanel>
    <TextBlock Text="Name:" Name="t1"></TextBlock>
    <TextBox Text="Content" RelativePanel.RightOf="t1" ></TextBox>
  </RelativePanel>
</Grid>
Run Code Online (Sandbox Code Playgroud)

网格也无济于事。

<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>
Run Code Online (Sandbox Code Playgroud)

显然,水平堆栈面板也没有魔法。

<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>
Run Code Online (Sandbox Code Playgroud)

垂直堆栈面板可以避免这个问题,但我更喜欢控件左侧的标签。

  <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>
Run Code Online (Sandbox Code Playgroud)

您是否有任何想法如何对齐基线,这对于许多输入控件和标签来说是/或者可能是一个不错的布局想法?

Dec*_*oon 4

我快速浏览了文档,我认为 UWP 中没有任何相当于 Android 基线对齐的东西。文本控件不会公开其基线的位置以供面板使用,因为它高度依赖于控件的模板(可以完全更改,这与在 Android 中视图的视觉外观有点困难)不同。编码)。

无论如何,通过检查文本框的可视化树,我发现最里面的 TextBoxView (实际显示和处理 TextBox 控件的文本输入的控件)以与 TextBlock 相同的方式呈现文本(意味着填充,这就是相同的)。因此,只要我们能够将 TextBlock 的上边缘与 TextBoxView 对齐,那么两个控件的文本将处于相同的垂直位置。当然,两个控件的字体和字体大小需要相同(默认情况下)。

TextBoxView 被其父 ScrollContentPresenter 下推 3px(有效像素),文本框边框下推 2px。因此,您只需向 TextBlock 添加 5px 的上边距,两个控件的文本就会对齐。

截屏

仅供参考,这是基于我正在使用的 SDK 版本 14393 提供的默认 TextBox 模板。Microsoft 可以使用新的 SDK 版本更改这些样式。


查看Android文档,View类有一个方法getBaseline;在 UWP 中,UIElement(或 FrameworkElement)没有此类等效项。搜索可视化树并尝试确定您看到的第一个文本元素的基线可能并不适用于所有情况(某些元素具有多个文本元素)。

如果您将拥有大量此类左标记元素,请参考以下建议:

  • 创建一个用户控件,并将标签和文本框放置在正确的位置。这样,您只需将边距硬编码在代码中的一个位置,如果您需要更改它,则只需更改一段代码。
  • TextBox 控件(与许多其他控件一样)具有 Header 属性,您可以在其中指定将显示在文本框正上方的文本。您可以更改模板,使标题位于文本框的左侧。

似乎推荐的方法是使用 Header 属性并将标签放在顶部。大多数 UWP 应用程序都会执行此操作(在 Groove 中编辑歌曲信息时、Edge 的设置窗格等)。这可能是因为在移动设备上显示时,没有太多的水平空间。