So I have a Path object that is implemented as follows:
<Path x:Name="arrow" Data="M0,0L0.67,0 4,2.67 7.25,0 8,0 8,0.67 4,4 0,0.75z" Fill="Black" Height="4" RenderTransformOrigin="0.5,0.5" Stretch="None" Width="8">
<Path.RenderTransform>
<TransformGroup>
<RotateTransform Angle="0"/>
<TranslateTransform/>
</TransformGroup>
</Path.RenderTransform>
</Path>
With this Path I have the following animation attached that works perfectly.
WORKING:
<VisualStateGroup x:Name="ExpandStateGroup">
<VisualState x:Name="Expanded">
<Storyboard>
<DoubleAnimation Duration="0:0:0.2" To="180" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(RotateTransform.Angle)" Storyboard.TargetName="arrow"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Collapsed">
<Storyboard>
<DoubleAnimation Duration="0:0:0.2" To="0" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(RotateTransform.Angle)" Storyboard.TargetName="arrow"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
However when I add the color animations neither of the animations work. Also, the expand seems to happen instantaneously rather than expanding smoothly. The Collapse works fine though.
NOT WORKING:
<VisualStateGroup x:Name="ExpandStateGroup">
<VisualState x:Name="Expanded">
<Storyboard>
<ColorAnimation To="Red" Duration="0:0:0.2" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="arrow" />
<DoubleAnimation Duration="0:0:0.2" To="180" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(RotateTransform.Angle)" Storyboard.TargetName="arrow"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Collapsed">
<Storyboard>
<ColorAnimation To="Black" Duration="0:0:0.2" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="arrow" />
<DoubleAnimation Duration="0:0:0.2" To="0" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(RotateTransform.Angle)" Storyboard.TargetName="arrow"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
It has to do with the coloranimation because when I try to perform the color animation by itself it doesn't work.
This is a part of the Telerik RadExpander user control.
If any other information is needed please don't hesitate to ask.
NOTE 1:
If I set the Fill color in the path declaration to black and set the collapsed fill color to green the arrow will start out as green, but as soon as I expand it turns black and never changes color again.
Note 2: When the coloranimation is set the doubleanimation never works.
Why can't I set Panel.ZIndex within a VisualStateManager?
I am building a carousel user interface and am struggling to find out why I am unable to set a value for Panel.ZIndex.
This XAML is embedded within a VisualState element:
<Storyboard>
<VisualState>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="MidRightRectangle"
Storyboard.TargetProperty="Rectangle.(Panel.ZIndex)">
<DiscreteObjectKeyFrame KeyTime="0" Value="4" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
The TargetProperty is not set correctly.
Try this instead.
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="VisualStateGroup">
<VisualState x:Name="ZIndexChanged">
<Storyboard>
<Int32AnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.ZIndex)" Storyboard.TargetName="MidRightRectangle">
<EasingInt32KeyFrame KeyTime="0" Value="4"/>
</Int32AnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
I also learned from the previous answer that I can resolve the animation like this:
<Int32Animation Storyboard.TargetName="MidRightRectangle"
Storyboard.TargetProperty="(Panel.ZIndex)"
To="4"
Duration="0:0:.15">
</Int32Animation>
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>
How can I access the "image" from code behind in order to change its image source?
xaml code looks like this
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="Demo.ChartButton"
d:DesignWidth="100" d:DesignHeight="100">
<UserControl.Resources>
<Style x:Key="ButtonStyle1" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Duration="0" To="White" Storyboard.TargetProperty="(UIElement.Effect).(DropShadowEffect.Color)" Storyboard.TargetName="image" d:IsOptimized="True" />
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Effect).(DropShadowEffect.ShadowDepth)" Storyboard.TargetName="image" d:IsOptimized="True"/>
<DoubleAnimation Duration="0" To="5" Storyboard.TargetProperty="(UIElement.Effect).(DropShadowEffect.BlurRadius)" Storyboard.TargetName="image" d:IsOptimized="True"/>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Effect).(DropShadowEffect.Opacity)" Storyboard.TargetName="image" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimation Duration="0" To="AntiqueWhite" Storyboard.TargetProperty="(UIElement.Effect).(DropShadowEffect.Color)" Storyboard.TargetName="image" d:IsOptimized="True"/>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Effect).(DropShadowEffect.Opacity)" Storyboard.TargetName="image" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Effect).(DropShadowEffect.Opacity)" Storyboard.TargetName="image" d:IsOptimized="True"/>
<ColorAnimation Duration="0" To="#FFAFAFAF" Storyboard.TargetProperty="(UIElement.Effect).(DropShadowEffect.Color)" Storyboard.TargetName="image" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Image x:Name="image" RenderTransformOrigin="0,0" Source="/Demo;component/spreadsheet-icon.png" >
<Image.Effect>
<DropShadowEffect ShadowDepth="0" BlurRadius="10" Color="Black" Opacity="1"/>
</Image.Effect>
</Image>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Button Content="" Margin="0,0,0,0" Style="{StaticResource ButtonStyle1}" Click="Button_Click" />
Any help is appreciated.
The only way to access this is to navigate the visual tree to locate the image. Using Linq-To-VisualTree, you can locate it as follows:
using LinqToVisualTree
private void Button_Click(object sender, EventArgs e)
{
Button button = sender as Button;
Image img = button.Descendants<Image>().Single() as Image;
img.Source = "..."
}
I am trying to create a Silverlight Toggle button style that would flip between a plus and a minus sign. Unfortunately it is always showing a minus sign. Can anyone tell me what's the problem with this style:
<Style x:Key="PlusMinusToggleButtonStyle" TargetType="ToggleButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Unchecked">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="UncheckedVisual" Storyboard.TargetProperty="Opacity" To="0" Duration="1" />
<DoubleAnimation Storyboard.TargetName="CheckedVisual" Storyboard.TargetProperty="Opacity" To="1" Duration="0" />
</Storyboard>
</VisualState>
<VisualState x:Name="Checked">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="UncheckedVisual" Storyboard.TargetProperty="Opacity" To="1" Duration="0" />
<DoubleAnimation Storyboard.TargetName="CheckedVisual" Storyboard.TargetProperty="Opacity" To="0" Duration="1" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid>
<Image x:Name="UncheckedVisual" Source="plus.png" Stretch="None" />
<Image x:Name="CheckedVisual" Source="minus.png" Stretch="None" />
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
You need to expand on the DoubleAnimation, put in KeyFrame Animation in it. Also set the base opacity to 0 and then fade in the respective one you need. For example:
<VisualState x:Name="Checked">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="CheckedVisual" Storyboard.TargetProperty="Opacity">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
Everytime a state is changed, it goes back to the base state then to the state that was called. Because a togglebutton is always in an on or off state, it will not be in an invisible state.