I have applied custom styling to a toggle button with control template. I have different background colour and border for default state, checked state and mouse hover. The problem is that when I hover over the checked state, WPF resets the style as if button is not checked (to default state appearance) even though actually the toggle button is checked.
Here is my code
<Style x:Key="MenuItem" TargetType="ToggleButton">
<Setter Property="Background" Value="Transparent"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand"/>
</Trigger>
</Style.Triggers>
</Style>
<ControlTemplate x:Key="MenuButton" TargetType="{x:Type ToggleButton}">
<Border x:Name="border" Padding="{TemplateBinding Padding}" Background="{TemplateBinding Background}" BorderThickness="4,0,0,0">
<StackPanel x:Name="MenuItemContainer" Orientation="Horizontal" Height="46" Margin="14,0,0,0" Background="Transparent">
<TextBlock x:Name="icon" Grid.Column="0" VerticalAlignment="Center" FontFamily="{StaticResource FontAwesome}" Foreground="#a7b1c2" FontSize="13" Text="{TemplateBinding Tag}" Margin="0,0,6,0"/>
<TextBlock x:Name="menuText" VerticalAlignment="Center" Foreground="#a7b1c2" FontSize="13" Text="{TemplateBinding Property=ContentControl.Content}"/>
</StackPanel>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Storyboard.TargetName="menuText" Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" To="White" Duration="0:0:0" />
<ColorAnimation Storyboard.TargetName="icon" Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" To="White" Duration="0:0:0"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background)" Storyboard.TargetName="border">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<SolidColorBrush Color="{StaticResource ColorMenuItemBg}" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush)" Storyboard.TargetName="border">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<SolidColorBrush Color="{StaticResource ColorMenuItemBorderHover}"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Normal"/>
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<Storyboard>
<ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderThickness)" Storyboard.TargetName="border">
<EasingThicknessKeyFrame KeyTime="0" Value="4,0,0,0"/>
</ThicknessAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush)" Storyboard.TargetName="border">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<SolidColorBrush Color="{StaticResource ColorMenuItemBorder}"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ColorAnimation Storyboard.TargetName="menuText" Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" To="White" Duration="0:0:0" />
<ColorAnimation Storyboard.TargetName="icon" Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" To="White" Duration="0:0:0"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background)" Storyboard.TargetName="border">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<SolidColorBrush Color="{StaticResource ColorMenuItemBg}"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Border>
</ControlTemplate>
<StackPanel>
<ToggleButton Tag="" Content="Home" Template="{StaticResource MenuButton}" Style="{StaticResource MenuItem}" />
<ToggleButton Tag="" Content="Reporting" Template="{StaticResource MenuButton}" Style="{StaticResource MenuItem}"/>
</StackPanel>
If you will click a toggle button you will see that it will get the green border and different background colour, however if you will hover over it and leave it, it will seem to appear as default button.
What am I missing here?
Thank you in Advance!
You defined two VisualtStateGroups in your template. This way you will always have two active states (one per group) for your ToggleButton. The problem is that you are setting the same object properties from VisualStates within two different groups. When you check a ToggleButton and the mouse leaves the button, the control updates its active VisualState for every group. Since your setting Border.Background and Border.BorderBrush from active states in both groups, the last state that gets applied wins (In your case CommonStates/Normal).
To fix this issue, try to avoid setting the same properties from mulitply groups. You can for example set the background of the Stackpanel in the MouseOver-State instead of the border background. This way the ToggleButton stays checked if the mouse leaves it because the "CommonState/Normal"-State will not reset the background of the border.
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Storyboard.TargetName="menuText" Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" To="White" Duration="0:0:0" />
<ColorAnimation Storyboard.TargetName="icon" Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" To="White" Duration="0:0:0"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background)" Storyboard.TargetName="MenuItemContainer">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<SolidColorBrush Color="{StaticResource ColorMenuItemBg}" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Normal"/>
</VisualStateGroup>
Hope this was helpful!
Related
this is my search box tag & I want to change his icon color to black from purple(Default color)
<SearchBox Height="50" Width="800" Margin="0,0,0,0" ></SearchBox>
I am Begineer in Xaml
Assuming that you are using a Universal Windows Application in Visual Studio, select your text box in the design viewer and right-click to open the menu. In the menu, select 'Edit Template' and 'Edit a Copy.' This will give you the option to select parts of your search box like the button to edit the background. Find this code in the generated App.xaml code to get started:
<Button x:Name="SearchButton" AutomationProperties.AccessibilityView="Raw" Background="#FFB49494" Grid.Column="1" FontWeight="{ThemeResource SearchBoxButtonThemeFontWeight}" Style="{StaticResource SearchButtonStyle}"/>
Go to the UI editor, right click on the control and select "Edit template" and "Edit copy". Now place the style code where you want, put Style="{StaticResource YourStyleName}" in your XAML code of the SearchBox and change the following section in your style. There are different "VisualStates" here. The state for "PointOver" already exists. Here you can either change the value for i. e "SearchBoxButtonPointerOverForegroundThemeBrush" directly or create a new brush to overrride the property. for the "normal" state, the StoryBoard entry must be copied and adapted.
I recommend to create a SolidColorBrush to override the ThemeResource.
<SolidColorBrush x:Key="SearchBoxButtonPointerOverBackgroundThemeBrush" Color="Gray"/>
<SolidColorBrush x:Key="SearchBoxButtonPointerOverForegroundThemeBrush" Color="White"/>
<SolidColorBrush x:Key="SearchBoxButtonBackgroundThemeBrush" Color="White"/>
<SolidColorBrush x:Key="SearchBoxButtonForegroundThemeBrush" Color="Black"/>
Before:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SearchGlyph" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SearchBoxButtonPointerOverForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SearchButtonBackground" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SearchBoxButtonPointerOverBackgroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
After:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SearchGlyph" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SearchBoxButtonForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SearchButtonBackground" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SearchBoxButtonBackgroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SearchGlyph" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SearchBoxButtonPointerOverForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SearchButtonBackground" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SearchBoxButtonPointerOverBackgroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
I'm developing a UWP app using c# and XAML; In the project I have a Resouce dictionary where several Path icons are, I want this icons to change the color when the parent control has the Pointer Over, I did make this on WPF app with Style data triggers:
<Style.Triggers>
<DataTrigger Binding="{Binding IsPressed, RelativeSource={RelativeSource AncestorType={x:Type Button}, Mode=FindAncestor}}" Value="True">
<Setter Property="Fill" Value="White"/>
</DataTrigger>
</Style.Triggers>
But in UWP I know this works diferent but I can't figure it out I firstly tried creating a Path Style:
<Style TargetType="Path">
<Setter Property="VisualStateManager.VisualStateGroups">
<Setter.Value>
<VisualStateGroup>
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="RootGrid">
<DiscreteObjectKeyFrame KeyTime="0" Value="#F2B71E"/>
</ObjectAnimationUsingKeyFrames>
<PointerUpThemeAnimation Storyboard.TargetName="RootGrid"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</Setter.Value>
</Setter>
</Style>
I know this is not correct because it need's to bind the parent state not this actual state, but not just that, this give me the error:
The property "VisualStateGroups" does not have an accessible setter.
So I opted for setting it up inside the path this way:
<Path x:Key="printIcon" Width="44" Height="43" Canvas.Left="16" Canvas.Top="17" Stretch="Fill" Data="F1 M 25,27L 25,17L 51,17L 51,27L 47,27L 47,21L 29,21L 29,27L 25,27 Z M 16,28L 60,28L 60,51L 51,51L 51,60L 25,60L 25,51L 16,51L 16,28 Z M 55,46L 55,33L 21,33L 21,46L 55,46 Z M 25,44L 25,39L 51,39L 51,44L 25,44 Z ">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="RootGrid">
<DiscreteObjectKeyFrame KeyTime="0" Value="#F2B71E"/>
</ObjectAnimationUsingKeyFrames>
<PointerUpThemeAnimation Storyboard.TargetName="RootGrid"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Path>
But now I'm dealing with
The name "PointerOver" is already defined in this scope.
And this don't fix the binding with the parent state
So I think I'm lost, how can I achieve changing the fill color or the path by the state of the parent?
You could do something like this...
"path" is stored as a string resource for reuse, then use the visual states of the UI control that already exist.
<Page.Resources>
<x:String x:Key="Icon_Printer">F1 M 25,27L 25,17L 51,17L 51,27L 47,27L 47,21L 29,21L 29,27L 25,27 Z M 16,28L 60,28L 60,51L 51,51L 51,60L 25,60L 25,51L 16,51L 16,28 Z M 55,46L 55,33L 21,33L 21,46L 55,46 Z M 25,44L 25,39L 51,39L 51,44L 25,44 Z</x:String>
<Color x:Key="Color_Base">#FFF2B71E</Color>
<Color x:Key="Color_Hover">#FFFFFFFF</Color>
<SolidColorBrush x:Key="Brush_Base" Color="{StaticResource Color_Base}" />
<SolidColorBrush x:Key="Brush_Hover" Color="{StaticResource Color_Hover}" />
<Style x:Key="PrinterButtonStyle" TargetType="Button" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid x:Name="RootGrid" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<Storyboard>
<PointerUpThemeAnimation Storyboard.TargetName="RootGrid"/>
</Storyboard>
</VisualState>
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="Icon">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource Brush_Hover}"/>
</ObjectAnimationUsingKeyFrames>
<PointerUpThemeAnimation Storyboard.TargetName="RootGrid"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<PointerDownThemeAnimation Storyboard.TargetName="RootGrid"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="Icon">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource SystemAltMediumColor}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Path x:Name="Icon" HorizontalAlignment="Center" VerticalAlignment="Center" Fill="{TemplateBinding Foreground}" Data="{StaticResource Icon_Printer}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Button Foreground="{StaticResource Brush_Base}" Style="{StaticResource PrinterButtonStyle}" />
</Grid>
I'm creating ToggleMenuFlyoutItems in code and adding them to an attached MenuFlyout's Items collection.
I set the IsTapEnabled of each to true, then add event handler to the Tapped event of each, and the tap event doesn't get fired when I tap on one of them in the list of the MenuFlyoutItem.
Also, the checked state is not visible if I set it from code.
Here is the code:
//XAML code:
<FlyoutBase.AttachedFlyout>
<MenuFlyout x:Name="flyout" Placement="Bottom">
</MenuFlyout>
</FlyoutBase.AttachedFlyout>
//C# code:
//...loop here
var subItem = new ToggleMenuFlyoutItem();
subItem.Text = "Test";
subItem.IsTapEnabled = true;
subItem.Tapped += SubItem_Tapped;
subItem.IsChecked = true;
subItem.IsEnabled = true;
flyoutMenu.Items.Add(subItem);
//...loop end here
//...
private void SubItem_Tapped(object sender, TappedRoutedEventArgs e)
{
Data data = (e.OriginalSource as FrameworkElement).DataContext as Data;
if (data != null)
{
//...
}
}
The flyout appears when I hold an item in the list to whose elements (stackpanel) this flyout is attached, but I can't figure out why the selected state is not shown and tapped event is not called...
The same code works fine in a Windows 10 UWP app, though...
Is there anything I'm missing while settings this up?
Is it not supposed to work this way, only by adding items in the XAML file?
There is nothing you've missed while setting this in code-behind. The problem here is that the implementation of ToggleMenuFlyoutItem on Windows Phone 8.1 is different from what on Windows 8.1 and also different from Windows 10 UWP apps.
Firstly, let's look at the style and template of ToggleMenuFlyoutItem in Windows 8.1 apps.
<!-- Default style for Windows.UI.Xaml.Controls.ToggleMenuFlyoutItem -->
<Style TargetType="ToggleMenuFlyoutItem">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Padding" Value="{ThemeResource MenuFlyoutItemThemePadding}" />
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
<Setter Property="FontWeight" Value="SemiBold" />
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleMenuFlyoutItem">
<Border x:Name="LayoutRoot"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="InnerBorder"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource MenuFlyoutItemPointerOverBackgroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TextBlock"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource MenuFlyoutItemPointerOverForegroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckGlyph"
Storyboard.TargetProperty="Fill">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource MenuFlyoutItemPointerOverForegroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="InnerBorder"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource MenuFlyoutItemPressedBackgroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TextBlock"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource MenuFlyoutItemPressedForegroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckGlyph"
Storyboard.TargetProperty="Fill">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource MenuFlyoutItemPressedForegroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TextBlock"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource MenuFlyoutItemDisabledForegroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckGlyph"
Storyboard.TargetProperty="Fill">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource MenuFlyoutItemDisabledForegroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="LayoutRoot"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource MenuFlyoutItemFocusedBackgroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TextBlock"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource MenuFlyoutItemFocusedForegroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckGlyph"
Storyboard.TargetProperty="Fill">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource MenuFlyoutItemFocusedForegroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused" />
<VisualState x:Name="PointerFocused" />
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Unchecked" />
<VisualState x:Name="Checked">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="CheckGlyph"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="InnerBorder">
<Grid Margin="{TemplateBinding Padding}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Path x:Name="CheckGlyph"
Margin="0,0,10,0"
Data="F1 M 0,58 L 2,56 L 6,60 L 13,51 L 15,53 L 6,64 z"
Fill="{TemplateBinding Foreground}"
Height="14"
Stretch="Fill"
Width="16"
Opacity="0"
FlowDirection="LeftToRight" />
<TextBlock x:Name="TextBlock"
Grid.Column="1"
Text="{TemplateBinding Text}"
TextTrimming="CharacterEllipsis"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Grid>
</Border>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
We can find the default style in generic.xaml by searching "ToggleMenuFlyoutItem". the "generic.xaml" file comes with Windows 8.1 SDK and usually is located in C:\Program Files (x86)\Windows Kits\8.1\Include\winrt\xaml\design folder. This location depends on the Windows SDK installation.
Then for the default style of ToggleMenuFlyoutItem in Windows Phone 8.1, we can find it in generic.xaml file in C:\Program Files (x86)\Windows Phone Kits\8.1\Include\abi\Xaml\Design folder.
<!-- Default style for Windows.UI.Xaml.Controls.ToggleMenuFlyoutItem -->
<Style TargetType="ToggleMenuFlyoutItem">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Padding" Value="{ThemeResource MenuFlyoutItemThemePadding}" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleMenuFlyoutItem">
<Border x:Name="LayoutRoot" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="PointerOver" />
<VisualState x:Name="Pressed">
<Storyboard>
<PointerDownThemeAnimation Storyboard.TargetName="InnerBorder" />
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TextBlock" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource MenuFlyoutItemDisabledForegroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualStateGroup.Transitions>
<VisualTransition From="Pressed" To="PointerOver">
<Storyboard>
<PointerUpThemeAnimation Storyboard.TargetName="InnerBorder" />
</Storyboard>
</VisualTransition>
<VisualTransition From="PointerOver" To="Normal">
<Storyboard>
<PointerUpThemeAnimation Storyboard.TargetName="InnerBorder" />
</Storyboard>
</VisualTransition>
<VisualTransition From="Pressed" To="Normal">
<Storyboard>
<PointerUpThemeAnimation Storyboard.TargetName="InnerBorder" />
</Storyboard>
</VisualTransition>
</VisualStateGroup.Transitions>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="InnerBorder" Padding="{TemplateBinding Padding}">
<TextBlock x:Name="TextBlock"
Text="{TemplateBinding Text}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
If you compare with these two styles, you will find in Windows Phone 8.1, there is only a TextBlock in the template. But in the template in Windows 8.1, there is also a Path named "CheckGlyph" with the "CheckStates" VisualStateGroup which is used to change its visibility.
And we can find the default style and template of ToggleMenuFlyoutItem in Windows 10 at ToggleMenuFlyoutItem styles and templates. It's like what in Windows 8.1 but also have some differences.
So the selected state can be shown on Windows 10, Windows 8.1 but not on Windows Phone 8.1.
Finally, for the Tapped event of ToggleMenuFlyoutItem, it can't be raised in Windows Phone 8.1. Actually, in Windows Phone 8.1 apps, all MenuFlyoutItem can not raise this event. To handle the selection of a menu item, we can use Click event of MenuFlyoutItem and ToggleMenuFlyoutItem instead.
I want to customize the circle and icon color of AppBarButton. So I tried following style but it does not work. In XAML, it show circle color green. But when I run the circle color is not changed
<Style x:Key="AppBarButtonStyle1" TargetType="AppBarButton">
<Setter Property="Foreground" Value="Yellow"/>
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
<Setter Property="FontWeight" Value="Normal"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="AppBarButton">
<Grid x:Name="RootGrid" Background="Transparent" Width="100">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ApplicationViewStates">
<VisualState x:Name="FullSize"/>
<VisualState x:Name="Compact">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="TextLabel">
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Width" Storyboard.TargetName="RootGrid">
<DiscreteObjectKeyFrame KeyTime="0" Value="60"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="BackgroundEllipse">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource AppBarItemPointerOverBackgroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="Content">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource AppBarItemPointerOverForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Stroke" Storyboard.TargetName="OutlineEllipse">
<DiscreteObjectKeyFrame KeyTime="0" Value="Red"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="BackgroundEllipse">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource AppBarItemForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="Content">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource AppBarItemPressedForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Stroke" Storyboard.TargetName="OutlineEllipse">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource AppBarItemDisabledForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="Content">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource AppBarItemDisabledForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="TextLabel">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource AppBarItemDisabledForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisualWhite"/>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisualBlack"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused"/>
<VisualState x:Name="PointerFocused"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<StackPanel Margin="0,14,0,13" VerticalAlignment="Top">
<Grid HorizontalAlignment="Center" Height="40" Margin="0,0,0,5" Width="40">
<Ellipse x:Name="BackgroundEllipse" Fill="{ThemeResource AppBarItemBackgroundThemeBrush}" Height="40" UseLayoutRounding="False" Width="40"/>
<Ellipse x:Name="OutlineEllipse" Height="40" Stroke="Green" StrokeThickness="4" UseLayoutRounding="False" Width="40"/>
<ContentPresenter x:Name="Content" AutomationProperties.AccessibilityView="Raw" Content="{TemplateBinding Icon}" Foreground="{TemplateBinding Foreground}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</Grid>
<TextBlock x:Name="TextLabel" Foreground="{ThemeResource AppBarItemForegroundThemeBrush}" FontSize="12" FontFamily="{TemplateBinding FontFamily}" TextAlignment="Center" TextWrapping="Wrap" Text="{TemplateBinding Label}" Width="88"/>
</StackPanel>
<Rectangle x:Name="FocusVisualWhite" IsHitTestVisible="False" Opacity="0" StrokeDashOffset="1.5" StrokeEndLineCap="Square" Stroke="{ThemeResource FocusVisualWhiteStrokeThemeBrush}" StrokeDashArray="1,1"/>
<Rectangle x:Name="FocusVisualBlack" IsHitTestVisible="False" Opacity="0" StrokeDashOffset="0.5" StrokeEndLineCap="Square" Stroke="{ThemeResource FocusVisualBlackStrokeThemeBrush}" StrokeDashArray="1,1"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
My BottomAppBar
<Page.BottomAppBar>
<CommandBar>
<AppBarButton Name="MenuButton" Style="{StaticResource AppBarButtonStyle1}" Icon="AllApps" Click="MenuBtn_Click" Label="Menu"/>
</CommandBar>
In Order to change the foreground color of the app bar button you need to set the foreground of the command bar then it will work. The only thing in that is everything in the command bar namely the ellipsis, the buttons and the secondary commands will be of same color.
<CommandBar Foreground=Green>
<AppBarButton Name="MenuButton" Icon="AllApps" Click="MenuBtn_Click" Label="Menu"/>
</CommandBar>
Hope this helps!
i am able to change the color of border background using checked event and manually changing background color every-time radio button is checked/unchecked , but i want to achieve the same using converter or visual states manager or any other efficient way, so how to achieve it .here is the xaml
<Border x:Name="br1" Background="Blue" >
<RadioButton Checked="radio1_Checked" x:Name="radio1" />
</Border>
<Border x:Name="br2" Background="Blue" >
<RadioButton Checked="radio2_Checked" x:Name="radio2" />
</Border>
i want to change the color of border background whenever radio-button is checked and unchecked so how to achieve it
There are several different solutions possible, depending on the amount of work, flexibility and re-usability you're looking after.
EDIT: Code below is for Windows (Phone) 8.1 RT and not for Windows Phone Silverlight. Leaving it here for future reference though, as Silverlight will be replaced by Windows Runtime on Windows 10 anyway.
As the standard RadioButton already has a border built-in its visual tree, and for highest flexibility and re-usability I've created a custom control (called Templated Control in Visual Studio item templates) derived from the RadioButton.
I provided a CheckedBrush and UncheckedBrush (default Red/Transparent) so you can customize to your wish. Setting one of these values in XAML will override the default values.
The code of the custom control:
public sealed class MyRadioButton : RadioButton
{
public MyRadioButton()
{
this.DefaultStyleKey = typeof(MyRadioButton);
UnCheckedBrush = new SolidColorBrush(Colors.Transparent);
CheckedBrush = new SolidColorBrush(Colors.Red);
this.Checked += (sender, args) =>
{
this.CustomBackground = CheckedBrush;
};
this.Unchecked += (sender, args) =>
{
this.CustomBackground = UnCheckedBrush;
};
}
public static readonly DependencyProperty CustomBackgroundProperty = DependencyProperty.Register(
"CustomBackground", typeof (Brush), typeof (MyRadioButton), new PropertyMetadata(default(Brush)));
public static readonly DependencyProperty CheckedBrushProperty = DependencyProperty.Register(
"CheckedBrush", typeof(Brush), typeof(MyRadioButton), new PropertyMetadata(default(Brush)));
public static readonly DependencyProperty UnCheckedBrushProperty = DependencyProperty.Register(
"UnCheckedBrush", typeof(Brush), typeof(MyRadioButton), new PropertyMetadata(default(Brush)));
public Brush CustomBackground
{
get { return (Brush) GetValue(CustomBackgroundProperty); }
set { SetValue(CustomBackgroundProperty, value); }
}
public Brush CheckedBrush
{
get { return (Brush) GetValue(CheckedBrushProperty); }
set { SetValue(CheckedBrushProperty, value); }
}
public Brush UnCheckedBrush
{
get { return (Brush) GetValue(UnCheckedBrushProperty); }
set { SetValue(UnCheckedBrushProperty, value); }
}
}
Next step is providing the style in the Themes/Generic.xaml file, this is a slightly tweaked style (for the background) from the default RadioButton style:
<Style TargetType="local:MyRadioButton">
<Setter Property="Foreground" Value="{ThemeResource RadioButtonContentForegroundThemeBrush}"/>
<Setter Property="Padding" Value="1,4,0,0" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Top" />
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:MyRadioButton">
<Border Background="{TemplateBinding CustomBackground}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundEllipse"
Storyboard.TargetProperty="Fill">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource RadioButtonPointerOverBackgroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundEllipse"
Storyboard.TargetProperty="Stroke">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource RadioButtonPointerOverBorderThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckGlyph"
Storyboard.TargetProperty="Fill">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource RadioButtonPointerOverForegroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundEllipse"
Storyboard.TargetProperty="Fill">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource RadioButtonPressedBackgroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundEllipse"
Storyboard.TargetProperty="Stroke">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource RadioButtonPressedBorderThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckGlyph"
Storyboard.TargetProperty="Fill">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource RadioButtonPressedForegroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundEllipse"
Storyboard.TargetProperty="Fill">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource RadioButtonDisabledBackgroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundEllipse"
Storyboard.TargetProperty="Stroke">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource RadioButtonDisabledBorderThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckGlyph"
Storyboard.TargetProperty="Fill">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource RadioButtonDisabledForegroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource RadioButtonContentDisabledForegroundThemeBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="CheckGlyph"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0" />
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked" />
<VisualState x:Name="Indeterminate" />
</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>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="29" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid VerticalAlignment="Top">
<Ellipse x:Name="BackgroundEllipse"
Width="23"
Height="23"
UseLayoutRounding="False"
Fill="{ThemeResource RadioButtonBackgroundThemeBrush}"
Stroke="{ThemeResource RadioButtonBorderThemeBrush}"
StrokeThickness="{ThemeResource RadioButtonBorderThemeThickness}" />
<Ellipse x:Name="CheckGlyph"
Width="13"
Height="13"
UseLayoutRounding="False"
Opacity="0"
Fill="{ThemeResource RadioButtonForegroundThemeBrush}" />
<Rectangle x:Name="FocusVisualWhite"
Stroke="{ThemeResource FocusVisualWhiteStrokeThemeBrush}"
StrokeEndLineCap="Square"
StrokeDashArray="1,1"
Opacity="0"
StrokeDashOffset="1.5"
Width="29"
Height="29" />
<Rectangle x:Name="FocusVisualBlack"
Stroke="{ThemeResource FocusVisualBlackStrokeThemeBrush}"
StrokeEndLineCap="Square"
StrokeDashArray="1,1"
Opacity="0"
StrokeDashOffset="0.5"
Width="29"
Height="29" />
</Grid>
<ContentPresenter x:Name="ContentPresenter"
Content="{TemplateBinding Content}"
ContentTransitions="{TemplateBinding ContentTransitions}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Grid.Column="1"
AutomationProperties.AccessibilityView="Raw"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The only things changed from the default template is dropping the Background property and changing the Background on the Border control.
You're all set to use it:
<StackPanel Margin="100">
<RadioButton Content="Check 1" />
<local:MyRadioButton CheckedBrush="Blue" Content="Check 2" />
<local:MyRadioButton CheckedBrush="Green" Content="Check 3" />
</StackPanel>
I would implement a view-model class (see MVVM pattern) and implement two DependencyPropery's one with the checkbox-state and one with the border-color. Bind the corresponding XAML attributes to these properties using data-binding. When checkbox-state changes also raise the PropertyChanged event for the border color. Done.