HCL
HCL

Reputation: 36785

AppBarButtonStyle works not reliable for ToggleButton controls

Although the comment of the AppBarButtonStyle of the StandardStyles.xaml-ResourceDictionary states, that it can be used for Buttons and ToggleButtons, it does not behave reliable for ToggleButton controls.

Applied to a ToggleButton, the Outline is missing, and in some occasions, the Unchecked-state will be rendered as Checked. Moreover, the style references an Element named "BackgroundCheckedGlyph" which is not defined and leads to debug-errors when used in an AppBar.

Has someone already found or built a working Style for Buttons and ToggleButtons?

Upvotes: 3

Views: 1337

Answers (3)

Shawn Kendrot
Shawn Kendrot

Reputation: 12465

I've found that if I set the VisualState of the ToggleButton manually then the style works just fine (after adding the missing TextBlock). Not sure why this works (or why it's not working to begin with...)

See this post for more information.

Upvotes: 1

Carlos P
Carlos P

Reputation: 3989

There are clearly some issues with StandardStyles.xaml and ToggleButtons in RTM.

While HCL's attempt to fix this is a good start, there are still some issues, by HCL's own admission.

Until this is fixed by MS, I think it's best to use an entirely separate style for ToggleButtons. There is a working Style at this MS forum page which I've reproduced below - so far, it seems to function perfectly.

<Style x:Key="ToggleAppBarButtonStyle" TargetType="ToggleButton">
    <Setter Property="Foreground" Value="{StaticResource AppBarItemForegroundThemeBrush}"/>
    <Setter Property="VerticalAlignment" Value="Stretch"/>
    <Setter Property="FontFamily" Value="Segoe UI Symbol"/>
    <Setter Property="FontWeight" Value="Normal"/>
    <Setter Property="FontSize" Value="20"/>
    <Setter Property="AutomationProperties.ItemType" Value="App Bar ToggleButton"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ToggleButton">
                <Grid x:Name="RootGrid" Width="100" Background="Transparent">
                    <StackPanel VerticalAlignment="Top" Margin="0,12,0,11">
                        <Grid Width="40" Height="40" Margin="0,0,0,5" HorizontalAlignment="Center">
                            <TextBlock x:Name="BackgroundGlyph" Text="&#xE0A8;" FontFamily="Segoe UI Symbol" FontSize="53.333" Margin="-4,-19,0,0" Foreground="{StaticResource AppBarItemBackgroundThemeBrush}"/>
                            <TextBlock x:Name="OutlineGlyph" Text="&#xE0A7;" FontFamily="Segoe UI Symbol" FontSize="53.333" Margin="-4,-19,0,0"/>
                            <ContentPresenter x:Name="Content" HorizontalAlignment="Center" Margin="-1,-1,0,0" VerticalAlignment="Center"/>
                        </Grid>
                        <TextBlock
                            x:Name="TextLabel"
                            Text="{TemplateBinding AutomationProperties.Name}"
                            Foreground="{StaticResource AppBarItemForegroundThemeBrush}"
                            Margin="0,0,2,0"
                            FontSize="12"
                            TextAlignment="Center"
                            Width="88"
                            MaxHeight="32"
                            TextTrimming="WordEllipsis"
                            Style="{StaticResource BasicTextStyle}"/>
                    </StackPanel>
                    <Rectangle
                            x:Name="FocusVisualWhite"
                            IsHitTestVisible="False"
                            Stroke="{StaticResource FocusVisualWhiteStrokeThemeBrush}"
                            StrokeEndLineCap="Square"
                            StrokeDashArray="1,1"
                            Opacity="0"
                            StrokeDashOffset="1.5"/>
                    <Rectangle
                            x:Name="FocusVisualBlack"
                            IsHitTestVisible="False"
                            Stroke="{StaticResource FocusVisualBlackStrokeThemeBrush}"
                            StrokeEndLineCap="Square"
                            StrokeDashArray="1,1"
                            Opacity="0"
                            StrokeDashOffset="0.5"/>

                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal"/>
                            <VisualState x:Name="PointerOver">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGlyph" Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemPointerOverBackgroundThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemPointerOverForegroundThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Pressed"/>
                            <VisualState x:Name="Disabled"/>
                            <VisualState x:Name="Checked">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="OutlineGlyph" Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemForegroundThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGlyph" Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemForegroundThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemPressedForegroundThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="CheckedPointerOver">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="OutlineGlyph" Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemForegroundThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGlyph" Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemForegroundThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemPressedForegroundThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="CheckedPressed"/>
                            <VisualState x:Name="CheckedDisabled"/>
                            <VisualState x:Name="Indeterminate"/>
                            <VisualState x:Name="IndeterminatePointerOver"/>
                            <VisualState x:Name="IndeterminatePressed"/>
                            <VisualState x:Name="IndeterminateDisabled"/>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="FocusStates">
                            <VisualState x:Name="Focused">
                                <Storyboard>
                                    <DoubleAnimation
                                            Storyboard.TargetName="FocusVisualWhite"
                                            Storyboard.TargetProperty="Opacity"
                                            To="1"
                                            Duration="0"/>
                                    <DoubleAnimation
                                            Storyboard.TargetName="FocusVisualBlack"
                                            Storyboard.TargetProperty="Opacity"
                                            To="1"
                                            Duration="0"/>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Unfocused" />
                            <VisualState x:Name="PointerFocused" />
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Upvotes: 4

HCL
HCL

Reputation: 36785

Here the result of my own trials to fix the Style. It seems to work (I have looked at it in the "Light"-theme and in the "HighContrast"- Theme. I have found some minor drawbacks, but it seems to me better than the original.
If I invest more time in this, I will post the improved Version. If you use this Style and improve it yourself, feel free to Change my Version.

<Style x:Key="AppBarButtonStyle" TargetType="ButtonBase">
    <Setter Property="Foreground" Value="{StaticResource AppBarItemForegroundThemeBrush}"/>
    <Setter Property="VerticalAlignment" Value="Stretch"/>
    <Setter Property="FontFamily" Value="Segoe UI Symbol"/>
    <Setter Property="FontWeight" Value="Normal"/>
    <Setter Property="FontSize" Value="20"/>
    <Setter Property="AutomationProperties.ItemType" Value="App Bar Button"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ButtonBase">
                <Grid x:Name="RootGrid" Width="100" Background="Transparent">
                    <StackPanel VerticalAlignment="Top" Margin="0,12,0,11">
                        <Grid Width="40" Height="40" Margin="0,0,0,5" HorizontalAlignment="Center">
                            <TextBlock x:Name="BackgroundGlyph" Text="&#xE0A8;" FontFamily="Segoe UI Symbol" FontSize="53.333" Margin="-4,-19,0,0" Foreground="{StaticResource AppBarItemBackgroundThemeBrush}"/>

                            <!-- The following TextBlock seemed to be missing in the original template -->
                            <TextBlock x:Name="BackgroundCheckedGlyph" Visibility="Collapsed" Text="&#xE0A8;" FontFamily="Segoe UI Symbol" FontSize="53.333" Margin="-4,-19,0,0" Foreground="{StaticResource AppBarItemForegroundThemeBrush}"/>

                            <TextBlock x:Name="OutlineGlyph" Text="&#xE0A7;" FontFamily="Segoe UI Symbol" FontSize="53.333" Margin="-4,-19,0,0"/>
                            <ContentPresenter x:Name="Content" HorizontalAlignment="Center" Margin="-1,-1,0,0" VerticalAlignment="Center"/>
                        </Grid>
                        <TextBlock
                            x:Name="TextLabel"
                            Text="{TemplateBinding AutomationProperties.Name}"
                            Foreground="{StaticResource AppBarItemForegroundThemeBrush}"
                            Margin="0,0,2,0"
                            FontSize="12"
                            TextAlignment="Center"
                            Width="88"
                            MaxHeight="32"
                            TextTrimming="WordEllipsis"
                            Style="{StaticResource BasicTextStyle}"/>
                    </StackPanel>
                    <Rectangle
                            x:Name="FocusVisualWhite"
                            IsHitTestVisible="False"
                            Stroke="{StaticResource FocusVisualWhiteStrokeThemeBrush}"
                            StrokeEndLineCap="Square"
                            StrokeDashArray="1,1"
                            Opacity="0"
                            StrokeDashOffset="1.5"/>
                    <Rectangle
                            x:Name="FocusVisualBlack"
                            IsHitTestVisible="False"
                            Stroke="{StaticResource FocusVisualBlackStrokeThemeBrush}"
                            StrokeEndLineCap="Square"
                            StrokeDashArray="1,1"
                            Opacity="0"
                            StrokeDashOffset="0.5"/>

                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="ApplicationViewStates">
                            <VisualState x:Name="FullScreenLandscape"/>
                            <VisualState x:Name="Filled"/>
                            <VisualState x:Name="FullScreenPortrait">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="TextLabel" Storyboard.TargetProperty="Visibility">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Width">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="60"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Snapped">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="TextLabel" Storyboard.TargetProperty="Visibility">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Width">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="60"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal">                                    
                                <!-- The following animations are here, because I was not able to reset the Glyphs states in the Unchecked state.
                                     I hope that this does not produces any sideeffects  -->
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundCheckedGlyph" Storyboard.TargetProperty="Visibility">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
                                    </ObjectAnimationUsingKeyFrames>                                        
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemForegroundThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="PointerOver">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGlyph" Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemPointerOverBackgroundThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>

                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundCheckedGlyph" Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemPointerOverBackgroundThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>

                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemPointerOverForegroundThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Pressed">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="OutlineGlyph" Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemForegroundThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGlyph" Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemForegroundThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>

                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundCheckedGlyph" Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemForegroundThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>

                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemPressedForegroundThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Disabled">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="OutlineGlyph" Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemDisabledForegroundThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemDisabledForegroundThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="TextLabel" Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemDisabledForegroundThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="FocusStates">
                            <VisualState x:Name="Focused">
                                <Storyboard>
                                    <DoubleAnimation
                                            Storyboard.TargetName="FocusVisualWhite"
                                            Storyboard.TargetProperty="Opacity"
                                            To="1"
                                            Duration="0"/>
                                    <DoubleAnimation
                                            Storyboard.TargetName="FocusVisualBlack"
                                            Storyboard.TargetProperty="Opacity"
                                            To="1"
                                            Duration="0"/>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Unfocused" />
                            <VisualState x:Name="PointerFocused" />
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="CheckStates">
                            <VisualState x:Name="Checked">
                                <Storyboard>                                        
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundCheckedGlyph" Storyboard.TargetProperty="Visibility">                                            
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>                                            
                                    </ObjectAnimationUsingKeyFrames>

                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="Foreground">                                            
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemPressedForegroundThemeBrush}"/>                                            
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Unchecked"><!-- This state seems to me as not working. Am I right? -->                                          
                            </VisualState>
                            <VisualState x:Name="Indeterminate">                                    

                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Upvotes: 0

Related Questions