Reputation: 7414
I am trying to use the AppBar for the first time and am having some difficulties with understanding how to do what I want the AppBar to do, stylistically.
The following are some data templates I've defined so I can use icons on my buttons within the AppBar. I didn't like the stock AppBarButton
as it stacked the button and icon on top of each other. I wasn't able to see anyway of making them stack horizontally, so I just used custom button templates.
<DataTemplate x:Key="NewFolderIconTemplate">
<Path Data="M10,4L12,6H20A2,2 0 0,1 22,8V18A2,2 0 0,1 20,20H4C2.89,20 2,19.1 2,18V6C2,4.89 2.89,4 4,4H10M15,9V12H12V14H15V17H17V14H20V12H17V9H15Z"
Fill="Black"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Width="24"
Height="24"
Margin="0 0 10 0"/>
</DataTemplate>
<DataTemplate x:Key="RefreshIconTemplate">
<Path Data="M19,12H22.32L17.37,16.95L12.42,12H16.97C17,10.46 16.42,8.93 15.24,7.75C12.9,5.41 9.1,5.41 6.76,7.75C4.42,10.09 4.42,13.9 6.76,16.24C8.6,18.08 11.36,18.47 13.58,17.41L15.05,18.88C12,20.69 8,20.29 5.34,17.65C2.22,14.53 2.23,9.47 5.35,6.35C8.5,3.22 13.53,3.21 16.66,6.34C18.22,7.9 19,9.95 19,12Z"
Fill="Black"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Width="24"
Height="24"
Margin="0 0 10 0"/>
</DataTemplate>
<DataTemplate x:Key="SortingIconTemplate">
<Path Data="M9.25,5L12.5,1.75L15.75,5H9.25M15.75,19L12.5,22.25L9.25,19H15.75M8.89,14.3H6L5.28,17H2.91L6,7H9L12.13,17H9.67L8.89,14.3M6.33,12.68H8.56L7.93,10.56L7.67,9.59L7.42,8.63H7.39L7.17,9.6L6.93,10.58L6.33,12.68M13.05,17V15.74L17.8,8.97V8.91H13.5V7H20.73V8.34L16.09,15V15.08H20.8V17H13.05Z"
Fill="Black"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Width="24"
Height="24"
Margin="0 0 10 0"/>
</DataTemplate>
Next is the actual AppBar. I've placed a series of buttons inside of a vertical stack panel, and put the stack panel within the app bar so I can get a vertical menu affect.
<Page.TopAppBar>
<AppBar HorizontalAlignment="Right"
Background="Transparent">
<AppBar.Resources>
<Style TargetType="Button"
x:Key="AppBarButton">
<Setter Property="HorizontalAlignment"
Value="Stretch" />
<Setter Property="Background"
Value="{ThemeResource ApplicationPageBackgroundThemeBrush}" />
<Setter Property="HorizontalContentAlignment"
Value="Left" />
</Style>
</AppBar.Resources>
<StackPanel HorizontalAlignment="Right">
<Button Command="{Binding Path=RefreshDirectoryListCommand}"
Style="{StaticResource AppBarButton}">
<StackPanel Orientation="Horizontal">
<ContentControl ContentTemplate="{StaticResource RefreshIconTemplate}"
VerticalAlignment="Center"
Margin="0 0 10 0"/>
<TextBlock Text="Refresh" />
</StackPanel>
</Button>
<Button Command="{Binding Path=CreateNewFolderCommand}"
Style="{StaticResource AppBarButton}">
<StackPanel Orientation="Horizontal">
<ContentControl ContentTemplate="{StaticResource NewFolderIconTemplate}"
VerticalAlignment="Center"
Margin="0 0 10 0"/>
<TextBlock Text="New Folder" />
</StackPanel>
</Button>
<Button Command="{Binding Path=SortListCommand}"
Style="{StaticResource AppBarButton}">
<StackPanel Orientation="Horizontal">
<ContentControl ContentTemplate="{StaticResource SortingIconTemplate}"
VerticalAlignment="Center"
Margin="0 0 10 0"/>
<TextBlock Text="Sort" />
</StackPanel>
</Button>
</StackPanel>
</AppBar>
</Page.TopAppBar>
There are a few problems with this that I'm trying to solve.
AppBar
pops out beside the AppBar, instead of beneath it, like a dropdown menu. Is there a way to configure the ApPBar to act this way, or do I have to style a custom control template?This seems more like an issue of my not knowing how to properly style things with triggers missing. What does everyone else typically do to achieve these affects, build custom control templates? If so, does Microsoft provide the XAML for the original template so you don't have to start 100% from scratch?
Upvotes: 1
Views: 930
Reputation: 15758
Yes, typically we need use custom control templates to achieve these affects. Microsoft has provided XAML code for the default template, you can find them at Default control styles and templates. Also in Visual Studio, open Document Outline view, select the control you want to edit and right click then select the "Edit Template" option and then "Edit a cpoy...". After this you can see the default template in the place you've chosen. By default, it's in your <Page.Resources>
. Here we need the template of AppBar and Button.
Is there a way to configure the ApPBar to act this way, or do I have to style a custom control template?
In the template of AppBar
, we can see following code:
<Grid x:Name="ContentRoot" ... >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
...
<ContentControl x:Name="ContentControl" ... />
<Button x:Name="ExpandButton" Grid.Column="1" ... >
...
<Grid>
So by default the content of the AppBar
shows at the left of the "ExpandButton". If you want it displays under "ExpandButton", you need completely rewrite its template to your own.
UWP apps don't seem to have triggers anymore, so what is the best way to change how the mouse over looks?
In UWP we use VisualState
instead of triggers to change control's visual appearance in different state. And in the template of Button
, it has following code:
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseMediumLowBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseHighBrush}" />
</ObjectAnimationUsingKeyFrames>
<PointerUpThemeAnimation Storyboard.TargetName="RootGrid" />
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlBackgroundBaseMediumLowBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightTransparentBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseHighBrush}" />
</ObjectAnimationUsingKeyFrames>
<PointerDownThemeAnimation Storyboard.TargetName="RootGrid" />
</Storyboard>
</VisualState>
To remove the border when mouse over, we can remove
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseMediumLowBrush}" />
</ObjectAnimationUsingKeyFrames>
from "PointerOver" VisualState
.
What would be the best way to style this? I'd like to keep the blurring animation, and remove the transparency.
Similarly we can change
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlBackgroundBaseMediumLowBrush}" />
</ObjectAnimationUsingKeyFrames>
in "Pressed" VisualState
to remove the transparency.
I imagine this can be solved once I know how to solve the similar issue with borders and the transparency issue on the buttons.
Yes, this is the similar issue on the buttons. The "ExpandButton" has following style:
<Style x:Key="EllipsisButton" TargetType="Button">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Padding" Value="0,0,9,0"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Right"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Top"/>
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
<Setter Property="Width" Value="{ThemeResource AppBarExpandButtonThemeWidth}"/>
<Setter Property="UseSystemFocusVisuals" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ContentPresenter">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightListLowBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ContentPresenter">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightListMediumBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledBaseLowBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="ContentPresenter" AutomationProperties.AccessibilityView="Raw" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" ContentTemplate="{TemplateBinding ContentTemplate}" ContentTransitions="{TemplateBinding ContentTransitions}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
You will also need to change Background in "PointerOver" VisualState
. But please note that if your style is defined in <Page.Resources>
you need change this style's key to something else like "MyEllipsisButton" and in AppBar's template set this new style to the Button
named "EllipsisButton" or AppBar will still use "EllipsisButton" style that defined in system's Generic.xaml and your custom style won't work.
Upvotes: 2