垂直对齐以将文本框居中放置在命令栏内容内

3
我正在尝试将一个文本框垂直居中在命令栏内容中,但遇到了问题。
实际上,我有以下代码(请查看最后第三行):
<CommandBar Grid.Row="0" FlowDirection="LeftToRight">
    <AppBarButton x:Name="Back" Icon="Back" Label="Back" Click="Back_Click"/>
    <AppBarButton x:Name="Forward" Icon="Forward" Label="Forward" Click="Forward_Click"/>
    <AppBarButton x:Name="Refresh" Icon="Refresh" Label="Refresh" Click="Refresh_Click"/>
    <AppBarButton x:Name="Cancel" Icon="Cancel" Label="Cancel" Click="Refresh_Click"/>
    <AppBarButton x:Name="Home" Icon="Home" Label="Home" Click="Home_Click"/>
    <CommandBar.Content>
        <TextBox x:Name="Value"  VerticalAlignment="Center" KeyDown="Value_KeyDown" HorizontalAlignment="Center" Margin="0,0,0,0" Width="880"/>
    </CommandBar.Content>
</CommandBar>

问题在于我看到一些指南,人们确切地写下了它对他们有用......但对我来说不是这样。 我不确定该怎么做,我已经尝试使用Visual Studio 2017的设计视图使用网格,相对面板,堆栈面板等,但我没有找到解决方案。

enter image description here

P.S: @Xavier Xie - MSFT@Jeff R.都找到了一种方法,只有在应用按钮的标签显示时才能对齐,当它们不显示时,文本框似乎未对齐。 我正在寻找一种方式,在它们不显示和显示时都可以对齐它。(因此,当标签显示或不显示时,对齐必须通过某种方式自动更改)。 如果这不可能,我至少要求在标签不显示时对齐它(不像他们的回答)。

2个回答

3
您可以尝试为CommandBar设置VerticalContentAlignment="Center",如下所示:
<Page.BottomAppBar>
    <CommandBar Grid.Row="0" FlowDirection="LeftToRight" VerticalContentAlignment="Center">
        <AppBarButton x:Name="Back" Icon="Back" Label="Back" VerticalAlignment="Center" VerticalContentAlignment="Center"/>
        <AppBarButton x:Name="Forward" Icon="Forward" Label="Forward" VerticalAlignment="Bottom" VerticalContentAlignment="Center"/>
        <AppBarButton x:Name="Refresh" Icon="Refresh" Label="Refresh" VerticalContentAlignment="Center"/>
        <AppBarButton x:Name="Cancel" Icon="Cancel" Label="Cancel" VerticalContentAlignment="Center"/>
        <AppBarButton x:Name="Home" Icon="Home" Label="Home" VerticalContentAlignment="Center"/>
        <CommandBar.Content>
            <TextBox x:Name="Value"  Width="880"/>
        </CommandBar.Content>
    </CommandBar>
</Page.BottomAppBar>
< p > 【更新于2018/6/8】 enter image description here

enter image description here

【更新于2018/6/14】

在进行了大量测试并咨询了同事之后,我们找到了一种实现您目标的方法。

我正在寻求一种既适用于带标签又适用于不带标签的对齐方式。我将更新我的问题以明确解释这一点。

为了实现您的目标,请先查看CommandBar 样式和模板。请定位到CompactOpenUp VisualState。您可以看到它会对ContentTransform应用动画,并改变其Y轴位置。这就是当打开 CommandBar 时文本框垂直对齐的原因。

<VisualState x:Name="CompactOpenUp">
                        <Storyboard>
                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="ContentTransform" Storyboard.TargetProperty="Y">
                                <DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="{Binding TemplateSettings.CompactVerticalDelta, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
                            </DoubleAnimationUsingKeyFrames>
......

受此启发,当CommandBar关闭时,我们也可以动态更改文本框的Y轴位置,使其垂直对齐。然后,让我们定位到样式中的ContentControl。该控件实际上用于托管您的文本框。因此,我们可以为其定义一个如下所示的TranslateTransform

<ContentControl x:Name="ContentControl" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentTransitions="{TemplateBinding ContentTransitions}" Foreground="{TemplateBinding Foreground}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" IsTabStop="False" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}">
                        <ContentControl.RenderTransform>
                            <TranslateTransform x:Name="ContentControlTransform"></TranslateTransform>
                        </ContentControl.RenderTransform>
</ContentControl>

在此之后,我相信您已经知道我们需要在CompactClosed可视状态中定义动画。但是您需要考虑Y轴的值是否合适。如何计算这个值?让我们检查CompactOpenUp可视状态。它将TemplateSettings.CompactVerticalDelta绑定为其Y轴位置。在不同的可视状态下,CompactVerticalDelta将会动态地改变。因此,我们需要定义一个转换器来计算该值。
转换器类如下所示:
public class CompactVerticalDeltaConverter:IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {

        return (double)value/2;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

接下来,CompactClosed 可视状态应该如下所示:

<VisualState x:Name="CompactClosed">
        <Storyboard>
             <DoubleAnimationUsingKeyFrames Storyboard.TargetName="ContentControlTransform" Storyboard.TargetProperty="Y">
                  <DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="{Binding TemplateSettings.CompactVerticalDelta, RelativeSource={RelativeSource Mode=TemplatedParent},Converter={StaticResource CompactVerticalDeltaConverter}}"/>
             </DoubleAnimationUsingKeyFrames>
         </Storyboard>
</VisualState>

目前为止,我们已经达成了您的目标,请尝试一下。

在这里输入图片描述


@EnderLook Jeff R的建议是正确的。 VerticalContentAlignment="Center" 实际上是有效的。文本框与整个 AppBarButton 垂直对齐。 AppBarButton 具有图标和标签。当您设置 IsOpen="True" 时,您会看到它垂直对齐。否则,它看起来像没有垂直对齐,但实际上是垂直对齐的。请查看我的更新回复。 - Xie Steven
哦,我明白了。你说得对,我会点赞你的回答。但是我不能接受它,因为我正在寻找一种既可以带标签对齐,又可以不带标签对齐的方法。我会更新我的问题来明确解释这一点。 - Ender Look
我刚看到了你的回复,很抱歉之前没有看到。我为不得不问这个问题感到惭愧,但是...我应该在哪里分配VisualStateContentControl?我尝试直接放在CommandBar.Content上,但它说已经有一个Content属性。我还尝试将其放在相对面板中,与我添加的文本框和另一个UI元素一起,但它说UIElementCollection不能有那个。我也尝试在commanbar上,但这次错误是IObservableVector。我还尝试在外部使用<Style TargetType="CommandBar">,但没有头绪。 - Ender Look
如果您对UWP中的“转换器”不熟悉,请参阅IValueConverter接口 - Xie Steven
好的,谢谢你。我明天会阅读它(因为现在已经很晚了)。附言:当你说“您需要复制所有样式”时,您是指文字上真正需要设置的部分,还是那个巨大的样式代码?因为那已经是命令栏的默认样式,所以我认为不需要复制所有那些东西,对吧?如果我没有定义自己的样式,它会自动使用该变量的默认值,或者至少我已经在XAML样式指南上快速查看中了解到了这一点,是这样吗?好吧,等我有时间时,我会更深入地阅读它。 - Ender Look
显示剩余4条评论

1

由于CommandBar是一个内容控件,因此支持HorizontalContentAlignment和VerticalContentAlignment属性。请尝试以下操作:

<CommandBar Grid.Row="0" FlowDirection="LeftToRight" VerticalContentAlignment="Center">

1
奇怪,对我来说它运行得很好。尽管当CommandBar处于紧凑模式时,它看起来像在底部而不是居中。当CommandBar处于正常大小模式时,文本框对我来说绝对是居中的。 - Jeff R.
我们可能有不同版本的C#或.Net吗?我已经安装了最新版本的Visual Studio(v15.7.2),所以我有C# 7.1(我想),并且我有Microsoft.NETCore.UniversalWindowsPlataform v6.1.4。 - Ender Look

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接