Reputation: 2401
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.
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
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/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.
Upvotes: 3
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