MouseDown event doesn't fire if MouseLeave event exists - wpf

I have a custom button that I want to add animations to, but when I add the MouseLeave event and click the button while testing it fires the MouseLeave event instead of the MouseDown. When I remove the MouseLeave event it goes back to normal and fires the MouseDown event like expected.
<Style TargetType="{x:Type Button}" x:Key="CustomButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border CornerRadius="4" Background="Green">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Border.Triggers>
<EventTrigger RoutedEvent="Button.MouseDown">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
To="Red"
Duration="0:0:0.15" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Button.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
To="Blue"
Duration="0:0:0.15" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Button.MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
To="Green"
Duration="0:0:0.15" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Border.Triggers>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I have no idea why this happens so please help

You should handle the tunneling "Preview..." events where possible. In your case, handle the PreviewMouseDown event.
You should generally try to avoid event triggers to animate control states (or transitions to states). The recommended approach is to use the VisualStateManager to manage states.
Visit Microsoft Docs: Control Styles and Templates to learn about the defined states of every library control.
Your Style that uses the VisualStateManager to animate control state transitions (notice the cleaner look):
<Style TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="Border"
CornerRadius="4"
Background="Green">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition From="MouseOver"
To="Normal"
GeneratedDuration="0:0:1.5" />
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
To="Blue"
Duration="0:0:0.15" />
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimation Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
To="Red"
Duration="0:0:0.15" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Related

WPF Storyboard only fires once

can anyone check my code and tell me what's wrong with it?
This is the code i've been working on and i can't figure out why the mouseover event won't fire anymore after i clicked the button. please help, thanks!
UPDATE: I tried removing the IsPressed event, and somehow the code works perfectly, there is a conflict with the IsMouseover & IsPressed and i have no idea on how to fix it.
<Style x:Key="MediaControls" TargetType="{x:Type Button}">
<Setter Property="Focusable" Value="False"/>
<Setter Property="VerticalAlignment" Value="Bottom"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<ControlTemplate.Resources>
<Storyboard x:Key="FadeIn">
<DoubleAnimation Duration="0:0:0.15" Storyboard.TargetName="ImageContainer" Storyboard.TargetProperty="Opacity" To="0.8" />
</Storyboard>
<Storyboard x:Key="FadeOut">
<DoubleAnimation Duration="0:0:0.15" Storyboard.TargetName="ImageContainer" Storyboard.TargetProperty="Opacity" To="1" />
</Storyboard>
<Storyboard x:Key="ClickIn">
<DoubleAnimation Duration="0:0:0.20" Storyboard.TargetName="ImageContainer" Storyboard.TargetProperty="Opacity" To="0.5" />
</Storyboard>
<Storyboard x:Key="ClickOut">
<DoubleAnimation Duration="0:0:0.20" Storyboard.TargetName="ImageContainer" Storyboard.TargetProperty="Opacity" To="1" />
</Storyboard>
</ControlTemplate.Resources>
<Border x:Name="ImageContainer" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource FadeIn}" x:Name="FadeIn_BeginStoryboard" />
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource FadeOut}" x:Name="FadeOut_BeginStoryboard" />
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource ClickIn}" x:Name="ClickIn_BeginStoryboard" />
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource ClickOut}" x:Name="ClickOut_BeginStoryboard" />
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
You can set FillBehavior to Stop to make the animations stop covering the property when they are done.
Modify your resources section with the following code.
<ControlTemplate.Resources>
<Storyboard x:Key="FadeIn">
<DoubleAnimation Duration="0:0:0.15" Storyboard.TargetName="ImageContainer" Storyboard.TargetProperty="Opacity" To="0.8" />
</Storyboard>
<Storyboard x:Key="FadeOut">
<DoubleAnimation Duration="0:0:0.15" FillBehavior="Stop" Storyboard.TargetName="ImageContainer" Storyboard.TargetProperty="Opacity" To="1" />
</Storyboard>
<Storyboard x:Key="ClickIn">
<DoubleAnimation Duration="0:0:0.20" Storyboard.TargetName="ImageContainer" Storyboard.TargetProperty="Opacity" To="0.5" />
</Storyboard>
<Storyboard x:Key="ClickOut">
<DoubleAnimation Duration="0:0:0.20" FillBehavior="Stop" Storyboard.TargetName="ImageContainer" Storyboard.TargetProperty="Opacity" To="1" />
</Storyboard>
</ControlTemplate.Resources>
Simplify your ControlTemplate by using visual states:
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="Disabled"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<DoubleAnimation Duration="0:0:0.15"
Storyboard.TargetProperty="Opacity" To="0.8" />
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<DoubleAnimation Duration="0:0:0.20"
Storyboard.TargetProperty="Opacity" To="0.5" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="contentPresenter"
Focusable="False" RecognizesAccessKey="True"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Margin="{TemplateBinding Padding}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
</ControlTemplate>

VisualStateManager -- showing mouseover state when control is focused

I am creating a WPF button using Windows 8 styling (formerly metro).
I would like the focused state of the button to show with a solid background. When the mouse is over the control, I would like th background to darken slightly to create the visual cue that the button can be clicked.
Unfortunately, the XAML I've written below does not work. The focused state shows correctly, but when the mouse is over the control, the background does not darken as I would like it to.
<Color x:Key="DoxCycleGreen">
#FF8DC63F
</Color>
<!-- Soft Interface : DoxCycle Green -->
<Color x:Key="DoxCycleGreenSoft">
#FFC0DC8F
</Color>
<Style x:Key="MetroButton" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="RootElement">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="CommonStates">
<VisualState Name="Normal" />
<VisualState Name="MouseOver">
<Storyboard>
<ColorAnimation Storyboard.TargetName="BackgroundColor" Storyboard.TargetProperty="Color" To="{StaticResource DoxCycleGreen}" Duration="0:0:0.150" />
<ColorAnimation Storyboard.TargetName="FontColor" Storyboard.TargetProperty="Color" To="White" Duration="0:0:0.150" />
</Storyboard>
</VisualState>
<VisualState Name="Focused">
<Storyboard>
<ColorAnimation Storyboard.TargetName="BackgroundColor" Storyboard.TargetProperty="Color" To="{StaticResource DoxCycleGreenSoft}" Duration="0:0:0.150" />
<ColorAnimation Storyboard.TargetName="FontColor" Storyboard.TargetProperty="Color" To="White" Duration="0:0:0.150" />
</Storyboard>
</VisualState>
<VisualState Name="Pressed">
<Storyboard>
<ColorAnimation Storyboard.TargetName="BackgroundColor" Storyboard.TargetProperty="Color" To="Transparent" Duration="0:0:0.150" />
<ColorAnimation Storyboard.TargetName="FontColor" Storyboard.TargetProperty="Color" To="{StaticResource DoxCycleGreen}" Duration="0:0:0.150" />
</Storyboard>
</VisualState>
<VisualState Name="Disabled">
<Storyboard>
<ColorAnimation Storyboard.TargetName="BorderColor" Storyboard.TargetProperty="Color" To="DarkGray" Duration="0:0:0.1" />
<ColorAnimation Storyboard.TargetName="FontColor" Storyboard.TargetProperty="Color" To="DarkGray" Duration="0:0:0.1" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid Background="Transparent" >
<Border BorderThickness="1,1,1,1" Padding="2">
<Border.BorderBrush>
<SolidColorBrush x:Name="BorderColor" Color="{StaticResource DoxCycleGreen}"/>
</Border.BorderBrush>
<Border.Background>
<SolidColorBrush x:Name="BackgroundColor" Color="White"/>
</Border.Background>
<ContentPresenter
x:Name="ContentSite"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Content">
<TextBlock.Foreground>
<SolidColorBrush x:Name="FontColor" Color="{StaticResource DoxCycleGreen}"/>
</TextBlock.Foreground>
</ContentPresenter>
</Border>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I've now tested your code. You've got a couple of issues at play here. But the main issue is that a WPF control can only be in one Visual State of a particular State Group at a time. And in cases like you've got here, where the control can be both focused and moused-over, WPF has to make choice of which State to apply (it cannot apply both States since they are in the same State Group). So in this case it is just keeping it in the Focused state and not sending it to the MouseOver state.
A control can be in multiple states if each of those states are in different state groups. From this documentation:
Each VisualStateGroup contains a collection of VisualState objects that are mutually exclusive. That is, the control is always in exactly one state of in each VisualStateGroup.
So our first step to correcting this code is to include the proper state groups that will allow the button to be able to show its Focused state and then show its MouseOver state (other possibilities can be corrected by this change but that's the one you noticed in particular that you didn't get with your previous approach).
To do this, we need to be careful to name our state groups and (especially) our state names correctly. This is because the code internal to the Button class likely makes a call like VisualStateManager.GoToState(this, "VerySpecificStateName", true); (I have not inspected the actual source code of the Button class to verify this, but having written custom controls where I've needed to initiate the state changes, I know it must be something like that). In order to get a list of the state group and state names that we'll need, we could either use Expression Blend to "edit a copy" of the control template (which will populate the needed states for us), or find them here. That documentation shows us that we need a state group called "FocusStates" and two states in that group called "Focused" and "Unfocused" (along with other state groups and states). As an aside, to illustrate how the Button class is initiating its state changes by these specific named states, if you change your original code by replacing the "Focus" state name with "MisspelledFocus", you'll see that your button never enters that state.
Implementing this first change, we could end up with something like:
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Storyboard.TargetName="BackgroundColor"
Storyboard.TargetProperty="Color"
To="{StaticResource DoxCycleGreen}" Duration="0:0:0.150" />
<ColorAnimation Storyboard.TargetName="FontColor" Storyboard.TargetProperty="Color"
To="White" Duration="0:0:0.150" />
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimation Storyboard.TargetName="BackgroundColor"
Storyboard.TargetProperty="Color"
To="Transparent" Duration="0:0:0.150" />
<ColorAnimation Storyboard.TargetName="FontColor"
Storyboard.TargetProperty="Color"
To="{StaticResource DoxCycleGreen}" Duration="0:0:0.150" />
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ColorAnimation Storyboard.TargetName="BorderColor"
Storyboard.TargetProperty="Color" To="DarkGray" Duration="0:0:0.1" />
<ColorAnimation Storyboard.TargetName="FontColor"
Storyboard.TargetProperty="Color" To="DarkGray" Duration="0:0:0.1" />
</Storyboard>
</VisualState>
</VisualStateGroup>
<!-- Focus States -->
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<Storyboard>
<ColorAnimation Storyboard.TargetName="BackgroundColor"
Storyboard.TargetProperty="Color"
To="{StaticResource DoxCycleGreenSoft}" Duration="0:0:0.150" />
<ColorAnimation Storyboard.TargetName="FontColor"
Storyboard.TargetProperty="Color"
To="White" Duration="0:0:0.150" />
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
This somewhat solves the problem. However, if you're looking at this in Expression Blend, you'll notice a warning in the state group headings:
We are getting this warning because we are changing the value of an identical property/object pair in more than one state group - in this case the "Color" property of the object named "BackgroundColor". Why could this be an issue? Because of what I said earlier - the fact that a control can be in multiple states at once if those states are in different state groups. So if the user has given the button focus and the user has also moused-over the button, it could be ambiguous to WPF as to which animation to apply, since both states say to animate the same exact property but in different ways.
Also, this first change does not completely get us what we want. If you try giving the button focus, then hover over it, it correctly goes from "Normal", to "Focused", to "MouseOver". But if you now discontinue hovering, you'll see that the button does not return to its "Focused" state.
There are several approaches you could use to remedy this problem and achieve something similar to what you wanted, but just as an example, we could do something like this. (This may not be the cleanest implementation for this, but it fixes the common object/property issue.):
<Color x:Key="DoxCycleGreen">
#FF8DC63F
</Color>
<SolidColorBrush x:Key="DoxCycleGreenBrush" Color="{StaticResource DoxCycleGreen}" />
<!-- Soft Interface : DoxCycle Green -->
<Color x:Key="DoxCycleGreenSoft">
#FFC0DC8F
</Color>
<SolidColorBrush x:Key="DoxCycleGreenSoftBrush" Color="{StaticResource DoxCycleGreenSoft}" />
<Style x:Key="ButtonStyle1" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="RootElement">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Storyboard.TargetName="BackgroundColor"
Storyboard.TargetProperty="Color"
To="{StaticResource DoxCycleGreen}" Duration="0:0:0.150" />
<ColorAnimation Storyboard.TargetName="FontColor"
Storyboard.TargetProperty="Color"
To="White" Duration="0:0:0.150" />
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="MouseOverBorder">
<EasingDoubleKeyFrame KeyTime="0" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimation Storyboard.TargetName="BackgroundColor"
Storyboard.TargetProperty="Color"
To="Transparent" Duration="0:0:0.150" />
<ColorAnimation Storyboard.TargetName="FontColor"
Storyboard.TargetProperty="Color"
To="{StaticResource DoxCycleGreen}" Duration="0:0:0.150" />
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ColorAnimation Storyboard.TargetName="BorderColor"
Storyboard.TargetProperty="Color" To="DarkGray" Duration="0:0:0.1" />
<ColorAnimation Storyboard.TargetName="FontColor"
Storyboard.TargetProperty="Color" To="DarkGray" Duration="0:0:0.1" />
</Storyboard>
</VisualState>
</VisualStateGroup>
<!-- Focus States -->
<VisualStateGroup x:Name="FocusStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.15"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Focused">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)"
Storyboard.TargetName="FocusBorder">
<EasingDoubleKeyFrame KeyTime="0" Value="1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="ContentSiteWhiteForeground">
<EasingDoubleKeyFrame KeyTime="0" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid Background="Transparent" >
<Border x:Name="BaseBorder" BorderThickness="1,1,1,1">
<Border.BorderBrush>
<SolidColorBrush x:Name="BorderColor" Color="{StaticResource DoxCycleGreen}"/>
</Border.BorderBrush>
<Border.Background>
<SolidColorBrush x:Name="BackgroundColor" Color="White"/>
</Border.Background>
</Border>
<Border x:Name="FocusBorder"
BorderThickness="1,1,1,1"
Background="{DynamicResource DoxCycleGreenSoftBrush}"
Opacity="0" />
<Border x:Name="MouseOverBorder"
BorderThickness="1,1,1,1"
Background="{DynamicResource DoxCycleGreenBrush}"
Opacity="0" />
<ContentPresenter
x:Name="ContentSite"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Content" Margin="2">
<TextBlock.Foreground>
<SolidColorBrush x:Name="FontColor" Color="{StaticResource DoxCycleGreen}"/>
</TextBlock.Foreground>
</ContentPresenter>
<ContentPresenter
x:Name="ContentSiteWhiteForeground"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Content" Margin="2" Opacity="0">
<TextBlock.Foreground>
<SolidColorBrush Color="White" />
</TextBlock.Foreground>
</ContentPresenter>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Now you'll see that we have removed the ambiguity for WPF. And we see that it now handles the case of state changes from "Normal" to "Focus" to "MouseOver" and back to "Focus" correctly.
This is a small edit to Jason's answer. It turns out that his approach which uses two ContentPresenters breaks the operation of the short cut keys. I've made a small adjustment... the short cut keys now work, but the transition animation isn't quite as nice...
<Style x:Key="MetroButton" TargetType="{x:Type Button}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="MinHeight" Value="23"/>
<Setter Property="MinWidth" Value="75"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="RootElement">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Storyboard.TargetName="BackgroundColor"
Storyboard.TargetProperty="Color"
To="{StaticResource DoxCycleGreen}" Duration="0:0:0.150" />
<ColorAnimation Storyboard.TargetName="FontColor"
Storyboard.TargetProperty="Color"
To="White" Duration="0:0:0.150" />
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="MouseOverBorder">
<EasingDoubleKeyFrame KeyTime="0" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimation Storyboard.TargetName="BackgroundColor"
Storyboard.TargetProperty="Color"
To="Transparent" Duration="0:0:0.150" />
<ColorAnimation Storyboard.TargetName="FontColor"
Storyboard.TargetProperty="Color"
To="{StaticResource DoxCycleGreen}" Duration="0:0:0.150" />
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ColorAnimation Storyboard.TargetName="BorderColor"
Storyboard.TargetProperty="Color" To="DarkGray" Duration="0:0:0.1" />
<ColorAnimation Storyboard.TargetName="FontColor"
Storyboard.TargetProperty="Color" To="DarkGray" Duration="0:0:0.1" />
</Storyboard>
</VisualState>
</VisualStateGroup>
<!-- Focus States -->
<VisualStateGroup x:Name="FocusStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.15"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Focused">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)"
Storyboard.TargetName="FocusBorder">
<EasingDoubleKeyFrame KeyTime="0" Value="1"/>
</DoubleAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="FontColor" Storyboard.TargetProperty="Color">
<EasingColorKeyFrame KeyTime="0" Value="White"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid Background="Transparent" >
<Border x:Name="BaseBorder" BorderThickness="1,1,1,1">
<Border.BorderBrush>
<SolidColorBrush x:Name="BorderColor" Color="{StaticResource DoxCycleGreen}"/>
</Border.BorderBrush>
<Border.Background>
<SolidColorBrush x:Name="BackgroundColor" Color="White"/>
</Border.Background>
</Border>
<Border x:Name="FocusBorder"
BorderThickness="1"
Background="{DynamicResource DoxCycleGreenSoftBrush}"
Opacity="0" />
<Border x:Name="MouseOverBorder"
BorderThickness="1"
Background="{DynamicResource DoxCycleGreenBrush}"
Opacity="0" />
<ContentPresenter x:Name="ContentSite"
VerticalAlignment="Center"
HorizontalAlignment="Center"
RecognizesAccessKey="True"
ContentSource="Content" Margin="8,4">
<TextBlock.Foreground>
<SolidColorBrush x:Name="FontColor" Color="{StaticResource DoxCycleGreen}"/>
</TextBlock.Foreground>
</ContentPresenter>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Best way for creating Icons in Windows Store Applications (Windows 8 Metro)?

I just understand for creating back button in Windows Store App in visual studio 2012 , Microsoft use this Value/Key pairs
<x:String x:Key="BackButtonGlyph"></x:String>
 is a Unicode? If yes how can obtain the list of valid codes for Windows Store Application because I use some of them and It shows me a empty rectangle?
based on This article I create a style.
First, add string dictionary item in StandardStyle.xaml (top of the file)
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Default">
<x:String x:Key="DeleteButtonGlyph"></x:String>
</ResourceDictionary>
.
Then, add following style in another or same xaml file ( style file )
<Style x:Key="DeleteButtonStyle" TargetType="Button">
<Setter Property="MinWidth" Value="0"/>
<Setter Property="ToolTipService.ToolTip" Value="Delete Selected Word"></Setter>
<Setter Property="Margin" Value="5"/>
<Setter Property="VerticalAlignment" Value="Bottom"/>
<Setter Property="FontFamily" Value="Segoe UI Symbol"/>
<Setter Property="FontWeight" Value="Normal"/>
<Setter Property="FontSize" Value="24"/>
<Setter Property="AutomationProperties.AutomationId" Value="DeleteButton"/>
<Setter Property="AutomationProperties.Name" Value="Delete"/>
<Setter Property="AutomationProperties.ItemType" Value="Delete Button"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid x:Name="RootGrid" Width="80">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Text="" FontSize="32" Margin="15, 0,0,0"></TextBlock>
<TextBlock x:Name="BackgroundGlyph" FontSize="32" Margin="15,0,0,0" Text="" Foreground="{StaticResource BackButtonBackgroundThemeBrush}"/>
<TextBlock Grid.Column="0" Grid.Row="0" Margin="25, 9,0,0" x:Name="NormalGlyph" Text="{StaticResource DeleteButtonGlyph}" Foreground="{StaticResource BackButtonForegroundThemeBrush}"/>
<TextBlock Grid.Column="0" Grid.Row="0" Margin="25, 9,0,0" x:Name="ArrowGlyph" Text="{StaticResource DeleteButtonGlyph}" Foreground="{StaticResource BackButtonPressedForegroundThemeBrush}" Opacity="0"/>
<TextBlock Margin="0,10,0,5" Grid.Row="1" FontSize="12" Text="Delete Word" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
</Grid>
<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 BackButtonPointerOverBackgroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="NormalGlyph" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource BackButtonPointerOverForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGlyph" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource BackButtonForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation
Storyboard.TargetName="ArrowGlyph"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0"/>
<DoubleAnimation
Storyboard.TargetName="NormalGlyph"
Storyboard.TargetProperty="Opacity"
To="0"
Duration="0"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
</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>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
In regards to getting a list of valid codes, I would strongly recommend this application if you have a Windows 8 device to run it on. It provides a list of a large number of existing Windows 8 Dev icons and their matching codes. It also gives you a better idea of how they would appear in a Metro environment and the app also provides examples of XAML to use to present the icons within various structures, including within buttons, text boxes, or the AppBar.
As you can see in your link above you already have the Metro Icons as fonts but I would recommend using the application I give as a reference to easily find the code for each one.

XAML - VisualGroupState for HyperlinkButton (whats wrong?)

Trying to figure out what I'm doing wrong (first time playing with Visual States). Can anyone point me to my problem? The app is crashing ungracefully, nothing else to help beyond that.
Heres the xaml
<Style TargetType="HyperlinkButton">
<Setter Property="Foreground" Value="{StaticResource HyperlinkTextBrush}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="HyperlinkButton">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<Storyboard>
<ColorAnimation BeginTime="0" Duration="0.5"
Storyboard.TargetName="content"
Storyboard.TargetProperty="(Control.Foreground).(SolidColorBrush.Color)"
To="Red" />
</Storyboard>
</VisualState>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation BeginTime="0" Duration="0.5"
Storyboard.TargetName="content"
Storyboard.TargetProperty="(Control.Foreground).(SolidColorBrush.Color)"
To="White" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid>
<ContentPresenter x:Name="content" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Thanks!
There is 3 places which you should correct:
1) The VisualStateManager.VisualStateGroups tag must be situated inside the root control like a Grid and not in the ControlTemplate.
2) The ContentPresenter class doesn't have the Foreground property. But this property exists in the ContentControl class. After you replace this control, add explicit bindings for the properties Content and Foreground.
3) The value of the Duration property should be in seconds. Although you can use the expression Duration="1" which means 1 day, the value 0.5 crashes the application. Half of a second looks like 0:0:0.5.
Here is the fixed style:
<Style TargetType="HyperlinkButton">
<Setter Property="Foreground" Value="{StaticResource HyperlinkTextBrush}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="HyperlinkButton">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<Storyboard>
<ColorAnimation Duration="0:0:0.5"
Storyboard.TargetName="content"
Storyboard.TargetProperty="(Control.Foreground).(SolidColorBrush.Color)"
To="Red" />
</Storyboard>
</VisualState>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Duration="0:0:0.5"
Storyboard.TargetName="content"
Storyboard.TargetProperty="(Control.Foreground).(SolidColorBrush.Color)"
To="White" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentControl x:Name="content" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"
Foreground="{TemplateBinding Foreground}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Changing text foreground color on mouseover and selection with Silverlight 4 ListBox

I'm trying to accomplish the following scenario with a Silverlight ListBox:
Normal items have a foreground text color of black and background color of white
Selected items have a foreground text color of white and a background color of dark blue
On mouse-over the background becomes a orangish and the foreground text color is black
I have each of those pieces working individually but can't get them all working together. I started by retemplating the ListBoxItem, wrapping the ContentPresenter in a ContentControl and using Visual States to change the foreground and backgrounds for selected and mouseover states. But the selected and mouseover states can both apply simultaneously, which causes problems when you mouseover a selected item and then mouse out. The recommendation is to avoid changing a single property in states that are in different state groups. So I wrapped another ContentControl around the first content control, and tried changing the the parent ContentControl's foreground in one visual state and the child ContentControl's foreground in the other visual state. But it looks like ContentControl's don't inherit the foreground property from their parent, so that doesn't seem to work (even if I retemplate the ContentControl to remove the explicit foreground property setter).
So I'm a bit stuck - don't know what to try next. Here's the XAML from my most recent iteration
<Style x:Key="SimpleListBoxItem" TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<Storyboard>
<ColorAnimation Duration="0" To="Yellow" Storyboard.TargetName="ContentControlChild"
Storyboard.TargetProperty="(Control.Foreground).(SolidColorBrush.Color)" />
</Storyboard>
</VisualState>
<VisualState x:Name="MouseOver">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="Mouse_Over" />
<ColorAnimation Duration="0" To="{StaticResource G360-MainBlack}" Storyboard.TargetName="ContentControlChild"
Storyboard.TargetProperty="(Control.Foreground).(SolidColorBrush.Color)" />
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled"/>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Unfocused"/>
<VisualState x:Name="Focused">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="Selected1" />
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="SelectionStates">
<VisualState x:Name="Unselected">
<Storyboard>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="Selected1" />
</Storyboard>
</VisualState>
<VisualState x:Name="Selected">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="Selected1" />
<ColorAnimation Duration="0" To="White" Storyboard.TargetName="ContentControlParent"
Storyboard.TargetProperty="(Control.Foreground).(SolidColorBrush.Color)" />
</Storyboard>
</VisualState>
<VisualState x:Name="SelectedUnfocused">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="Selected1" />
<ColorAnimation Duration="0" To="White" Storyboard.TargetName="ContentControlParent"
Storyboard.TargetProperty="(Control.Foreground).(SolidColorBrush.Color)" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Rectangle x:Name="Selected1" Opacity="0" Fill="{StaticResource G360-ListSelected}" />
<Rectangle x:Name="Mouse_Over" RadiusX="2" RadiusY="2" Stroke="{StaticResource ListBorderSelected}" Opacity="0" Margin="2" Fill="{StaticResource -ListMouseOver}" />
<ContentControl x:Name="ContentControlParent">
<ContentControl x:Name="ContentControlChild">
<ContentControl.Style>
<Style TargetType="ContentControl">
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Top"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<ContentPresenter
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Cursor="{TemplateBinding Cursor}"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ContentControl.Style>
<ContentPresenter x:Name="ContextText" Content="{TemplateBinding Content}" VerticalAlignment="Center" Margin="8,5,4,5"/>
</ContentControl>
</ContentControl>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
ContentPresenters inherit the style attributes (font, foreground, etc...) from the parent, not ContentControl.
I agree with Rob that having two ContentControls is the solution that gives you the most control over the animations. This also allows to do some fade-in/fade-out transitions between the states, something that is difficult to achieve with just one element.
[edit] You don't want to template the ListBoxItem. Instead, work with the ItemContainerStyle. This is the best way to achieve what you want with the least headaches.
Cheers,
Laurent
I would create two ContentControls in the template, one of which has its colour modified by the "selected" stategroup, and another which is always orange but has its opacity modified by the mouseover stategroup.
Sounds like a waste but it gives you the most control over animations if you decide to bring them in...

Resources