Ender Look
Ender Look

Reputation: 2401

Vertical alignment to center a text box inside a Command bar Content

I am having a problem trying to center (vertically) a text box inside a Command Bar Content.

Actually I have this (look at the last third line):

<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>

The problem is that I have seen some guides where people write exactly that an it worked for them... but for me not. I am no sure what to do, I have tried with grid, relative panels, stack panels, etc using the design view of the Visual Studio 2017 as I could but I haven't found a solution.

enter image description here

P.S: Both @Xavier Xie - MSFT and @Jeff R. found a way to aling it only when the labels of the app buttons are showed, when they aren't the textbox seems unaligned. I'm looking for a way to aling it when they aren't showed and when they are showed. (So the alignment must change by some way automatly when the label are showed or not). If that isn't possible I'm looking for at least aling it when the labels aren't showed (not like they anwsers).

Upvotes: 3

Views: 1287

Answers (2)

Xie Steven
Xie Steven

Reputation: 8591

You could try to set VerticalContentAlignment="Center" for CommandBar like the following:

<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>

[Updated on 2018/6/8] enter image description here

enter image description here

[Updated on 2018/6/14]

After a lot of tests and consult with my colleagues, we found a way to achieve your target.

I am looking for a way to aling it both with label and without label. I'll update my question to explain that explicitly.

To achieve your target, let's first check CommandBar styles and templates. Please locate to CompactOpenUp VisualState. You could see that it applies an animation to ContentTransform and change its Y axis position. That's reason why the textbox will be vertical aligned when the CommandBar is opened.

<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>
......

Inspired by this, we also could dynamically change the textbox's Y axis position to make it vertical aligned when the CommandBar is closed. Then, let's locate to ContentControl in the style. This control actually is used to host your TextBox. So, we can define a TranslateTransform for it like the following:

<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>

After that, I believe you've known that we need to define an animation in CompactClosed visual state. But you need to think about if the value of Y axis is appropriate. How to calculate this value? Let's check the CompactOpenUp visual state. It binds TemplateSettings.CompactVerticalDelta as its Y axis position. The CompactVerticalDelta will be changed dynamically in different visual state. So, we need define a converter for calculating the value.

The converter class like the following:

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();
    }
}

Then, the CompactClosed visual state finally should like the following:

<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>

For now, we have achieved your target. Please try it.

enter image description here

Upvotes: 3

Jeff R.
Jeff R.

Reputation: 1521

Since the CommandBar is a Content Control it supports the HorizontalContentAlignment and VerticalContentAlignment properties. Try this:

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

Upvotes: 1

Related Questions