WPF Multiple Triggers & DataTrigger on Button Style - wpf

Working on a "data entry style" program. After a certain combination of data changes a property IsSaveNeeded (enum: Yes, No) is set to Yes and the Save button is suppose to flash.
I have been able to get the button to flash with a basic button
<!--Save Button-->
<Button Content=" Save
Settings
 to File" x:Name="SaveBtn" Command="{Binding SaveCMD}" Padding="10,5" Margin= "10,0" IsEnabled="{Binding SaveEnabled}"
Background="{StaticResource {x:Static SystemColors.ControlLightBrushKey}}">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSaveNeeded}" Value="Yes">
<DataTrigger.EnterActions>
<BeginStoryboard x:Name="FlashBackground">
<Storyboard BeginTime="00:00:00" RepeatBehavior="Forever" >
<ColorAnimation Storyboard.TargetProperty="Background.Color" Duration="00:00:00.75" AutoReverse="True" To="Red" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="FlashBackground" />
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
I have been required to make all the buttons a custom style button.
<!--My Custom Buton-->
<Style x:Key="myBtn" TargetType="{x:Type Button}">
<Setter Property="Background" Value="White" />
<Setter Property="Margin" Value="0" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Foreground" Value="{StaticResource myColorBrush}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid UseLayoutRounding="True" SnapsToDevicePixels="True">
<!--Button Content / DropShadow / Border-->
<Border Padding="{TemplateBinding Padding}" Background="{TemplateBinding Background}" CornerRadius="5" BorderThickness="1" BorderBrush="{StaticResource myColorBrush}">
<Border.Effect>
<DropShadowEffect ShadowDepth="4" Direction="330" Color="Black" Opacity="0.2" BlurRadius="4"/>
</Border.Effect>
</Border>
<Border Padding="{TemplateBinding Padding}" UseLayoutRounding="True" SnapsToDevicePixels="True">
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Text="{TemplateBinding Content}" SnapsToDevicePixels="True" >
<!--<TextBlock.Effect>
<DropShadowEffect ShadowDepth="4" Direction="330" Color="{StaticResource MyColor}" Opacity="0.3" BlurRadius="4"/>
</TextBlock.Effect>-->
</TextBlock>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="#FFC1C1C1" />
<Setter Property="Foreground" Value="#FFACA8A8" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource myHoverBrush}"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="{StaticResource myColorBrush}"/>
<Setter Property="Foreground" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
I need to add the IsSaveNeeded DataTrigger to this custom button style, myFlashingBtn, but when I do the Flashing works but the other Triggers stop working.
How do I incorporate the IsSaveNeeded Flashing into my custom button style and keep all the Triggers working? MultiTrigger and MultiDataTriggers haven't helped unless I wrote them wrong.

I believe you're looking for the BasedOn property (Style.BasedOn).
This allows you to inherit everything from a specific style and add to it.
<!--Save Button-->
<Button Content=" Save
Settings
 to File" x:Name="SaveBtn" Command="{Binding SaveCMD}" Padding="10,5" Margin= "10,0" IsEnabled="{Binding SaveEnabled}" >
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource myBtn}">
<Setter Property="Background" Value="{StaticResource {x:Static SystemColors.ControlLightBrushKey}}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsSaveNeeded}" Value="Yes">
<DataTrigger.EnterActions>
<BeginStoryboard x:Name="FlashBackground">
<Storyboard BeginTime="00:00:00" RepeatBehavior="Forever" >
<ColorAnimation Storyboard.TargetProperty="Background.Color" Duration="00:00:00.75" AutoReverse="True" To="Red" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="FlashBackground" />
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Edit: I moved the Background to a setter of the Style

Related

Animation causes button to become invisible

I've been trying to get a user control to animate when IsEnabled changes.
Loosely based on this post Button Blinking on DataTrigger
However, when I include the ControlTemplate style the button is invisible. :)
<UserControl x:Class="View.UserControls.MainButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="40" d:DesignWidth="300">
<UserControl.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="MinHeight" Value="24" />
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="Transparent"/>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="True">
<Trigger.EnterActions>
<BeginStoryboard Name="StartBlinking">
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)" To="Orange" Duration="00:00:00.4" RepeatBehavior="3" AutoReverse="True"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Trigger.ExitActions>
<RemoveStoryboard BeginStoryboardName="StartBlinking"/>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type StackPanel}">
<Setter Property="Orientation" Value="Horizontal" />
</Style>
<Style TargetType="{x:Type Image}">
<!--<Setter Property="Height" Value="32" />
<Setter Property="Width" Value="32" />-->
<Setter Property="Stretch" Value="Uniform" />
</Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Margin" Value="5 0 0 0" />
</Style>
</UserControl.Resources>
<Button Width="{Binding Width, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
Command="{Binding Command, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
ToolTip="{Binding ToolTip, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}">
<StackPanel>
<Image Source="{Binding ButtonImageSource, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" />
<TextBlock Text="{Binding ButtonText, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" />
</StackPanel>
</Button>
Move the triggers to the Style and avoid overriding the ControlTemplate if you want the Button to still look like a Button:
<Style TargetType="{x:Type Button}">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="MinHeight" Value="24" />
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="Transparent"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="True">
<Trigger.EnterActions>
<BeginStoryboard Name="StartBlinking">
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)" To="Orange" Duration="00:00:00.4" RepeatBehavior="3" AutoReverse="True"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Trigger.ExitActions>
<RemoveStoryboard BeginStoryboardName="StartBlinking"/>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
The template defines the visual appearance of the control. Anything not put there by the template isn't there. Your template puts no visual elements in the control. Therefore, there is nothing visual to be seen.
If you're replacing the template, at absolute minimum, you'll have to give it a ContentPresenter inside a Border that will show the blinking Background brush color:
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter
/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="True">
<Trigger.EnterActions>
<BeginStoryboard Name="StartBlinking">
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)" To="Orange" Duration="00:00:00.4" RepeatBehavior="3" AutoReverse="True"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Trigger.ExitActions>
<RemoveStoryboard BeginStoryboardName="StartBlinking"/>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
But if you're happy with the standard Button template, use mm8's approach instead, which leaves that in place. Rewriting standard templates usually turns out to be a lot more effort than it's worth, if you can find another way to do what you need to.

Button background color is not updating when button clicked

My WPF application is not updating button background for when button is clicked AND mouse cursor is over it. The backgrund color is still light green. Other property changes are working ok. What is wrong?
File ControlStyles.xaml
...
<Style TargetType="{x:Type Button}" x:Key="MyButton">
<Setter Property="Foreground" Value="Black"/>
<Setter Property="Background" Value="DarkCyan"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="FontSize" Value="20"/>
<Style.Triggers>
<Trigger Property="Control.IsMouseOver" Value="true">
<Setter Property="Control.FontStyle" Value="Italic"></Setter>
<Setter Property="Control.Foreground" Value="Red"></Setter>
<Setter Property="Control.Background" Value="black"></Setter>
</Trigger>
<Trigger Property="Button.IsPressed" Value="true">
<Setter Property="Control.Foreground" Value="Firebrick"></Setter>
<Setter Property="Control.Background" Value="Yellow"></Setter>
</Trigger>
</Style.Triggers>
</Style>
...
Window.xaml
...
<Button Name="btn7" Content="7" Grid.Column="0" Grid.Row="3" Style="{StaticResource MyButton}" Click="btn7_Click"/>
<Button Name="btn8" Content="8" Grid.Column="1" Grid.Row="3" Style="{StaticResource MyButton}" Click="btn8_Click"/>
...
See if this solves your problem :
<Style TargetType="{x:Type Button}" x:Key="MyButton">
<Setter Property="Foreground" Value="Black"/>
<Setter Property="Background" Value="DarkCyan"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="FontSize" Value="20"/>
<Style.Triggers>
<Trigger Property="Control.IsMouseOver" Value="true">
<Setter Property="Control.FontStyle" Value="Italic"></Setter>
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)" To="Black"/>
<ColorAnimation Storyboard.TargetProperty="(Button.Foreground).(SolidColorBrush.Color)" To="Red"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)" To="DarkCyan"/>
<ColorAnimation Storyboard.TargetProperty="(Button.Foreground).(SolidColorBrush.Color)" To="Black"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="Button.IsPressed" Value="true">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)" To="Yellow"/>
<ColorAnimation Storyboard.TargetProperty="(Button.Foreground).(SolidColorBrush.Color)" To="Firebrick"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
This is my solution with usage of ControlTemplate. It's important to use x:Name and TargetName inside of it.
ControlTemplate.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ControlTemplate TargetType="{x:Type Button}" x:Key="MyButtonTemplate">
<Border x:Name="tempBorder" CornerRadius="20" Margin="4" BorderThickness="1" BorderBrush="Black" Background="Gold">
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" Margin="8,6,8,6" ContentSource="Content" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="tempBorder" Property="Background" Value="MediumVioletRed"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="tempBorder" Property="Background" Value="LightPink"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ResourceDictionary>
ConstrolStyles.xaml:
...
<Style TargetType="{x:Type Button}" x:Key="MyButton">
<!-
<Setter Property="Foreground" Value="Black"/>
<Setter Property="Background" Value="DarkCyan"/>
-->
...
Window.xaml:
...
<Button Name="btnAdd" Content="Add" Grid.Column="4" Grid.Row="1" Style="{StaticResource MyButton}" Template="{StaticResource MyButtonTemplate}" />
...
App.xampl:
<Application x:Class="WpfApplication1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Styles/MyColors.xaml"/>
<ResourceDictionary Source="Styles/ControlStyles.xaml"/>
<ResourceDictionary Source="Styles/ControlTemplates.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

Path Animation into a Button

I have a button with a Path, What I want is that when I make a click over the button the path moves to the rigth side; I've added the style and the trigger to the button, but it doesn't work. I've tried to add the trigger to the ControlTemplate but it doesn't let me
If you have any suggestions, I'd appreciate it.
This is my code:
<Button x:Name="btnEnviarCorreo" Height="50" Width="100" Padding="5" Content="Enviar Correo" Margin="2,2" >
<Button.Style>
<Style TargetType="Button">
<Setter Property="Background" Value="SteelBlue"/>
<Setter Property="Foreground" Value="White" />
<Setter Property="FontSize" Value="15" />
<Setter Property="FontFamily" Value="./#Segoe UI" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border CornerRadius="4" Background="{TemplateBinding Background}">
<Grid>
<Path x:Name="PathIcon" Width="15" Height="25" Stretch="Fill" Fill="#E59400" HorizontalAlignment="Left" Margin="17,0,0,0" Data="F1M30.0833,22.1667L50.6665,37.6043 50.6665,38.7918 30.0833,53.8333 30.0833,22.1667z"/> <ContentPresenter x:Name="MyContentPresenter" Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,0,0,0" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#E59400" />
<Setter Property="Foreground" Value="White" />
<Setter TargetName="PathIcon" Property="Fill" Value="Black" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="OrangeRed" />
<Setter Property="Foreground" Value="White" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<EventTrigger RoutedEvent="Click">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="PathIcon" Storyboard.TargetProperty="RenderTransform.(TranslateTransform.X)" From="0" To="200" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Thanks for your time.
Add the following code somewhere inside ControlTemplate.Triggers block:
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation From="17,0,0,0" To="100, 0, 0, 0" Duration="0:0:1" Storyboard.TargetProperty="Margin"
Storyboard.TargetName="PathIcon"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
It's not perfect, you should work out to set some details on your own. I use animation for Margin within an EventTrigger. You can try to make some other experiments :D

XamlWriter skips "x:Name" attribute while saving ResourceDictionary

Here's custom style:
<Style TargetType="{x:Type Button}">
<Setter Property="Focusable" Value="false" />
<Setter Property="Background" Value="{StaticResource AppBackBrush}"/>
<Setter Property="Foreground" Value="{StaticResource AppBrush}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border BorderBrush="{StaticResource AppBrush}"
Name="content"
BorderThickness="1"
CornerRadius="3"
Background="{StaticResource AppBackBrush}"
>
<Grid Background="Transparent">
<Label Content="{TemplateBinding Content}"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Grid.Row="0" Grid.Column="0"
Background="Transparent"
Style="{x:Null}"
Foreground="{TemplateBinding Foreground}"
Padding="{TemplateBinding Padding}"/>
</Grid>
<Border.RenderTransform>
<!-- push the content a bit to the left and the top -->
<TranslateTransform x:Name="translation"
X="-1" Y="-1"/>
</Border.RenderTransform>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0"
To="0"
Storyboard.TargetName="translation"
Storyboard.TargetProperty="(TranslateTransform.X)"/>
<DoubleAnimation Duration="0:0:0"
To="0"
Storyboard.TargetName="translation"
Storyboard.TargetProperty="(TranslateTransform.Y)"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0"
To="-1"
Storyboard.TargetName="translation"
Storyboard.TargetProperty="(TranslateTransform.X)"/>
<DoubleAnimation Duration="0:0:0"
To="-1"
Storyboard.TargetName="translation"
Storyboard.TargetProperty="(TranslateTransform.Y)"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="content" Property="Opacity" Value="0.5" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I save this ResourceDictionary that contains this style to string like this:
XamlWriter.Save(s);
where s is ResourceDictionary. The problem is that when I get expected string, it looks so:
<Style TargetType=\"Button\" x:Key=\"{x:Type Button}\">
<Style.Resources>
<ResourceDictionary />
</Style.Resources>
<Setter Property=\"UIElement.Focusable\">
<Setter.Value>
<s:Boolean>False</s:Boolean>
</Setter.Value>
</Setter>
<Setter Property=\"Panel.Background\">
<Setter.Value>
<SolidColorBrush>#FFF1F2F4</SolidColorBrush>
</Setter.Value>
</Setter>
<Setter Property=\"TextElement.Foreground\">
<Setter.Value>
<SolidColorBrush>#FF13776A</SolidColorBrush>
</Setter.Value>
</Setter>
<Setter Property=\"Control.Template\">
<Setter.Value>
<ControlTemplate TargetType=\"Button\">
<Border BorderThickness=\"1,1,1,1\" CornerRadius=\"3,3,3,3\" BorderBrush=\"#FF13776A\" Background=\"#FFF1F2F4\" Name=\"content\">
<Border.RenderTransform>
<TranslateTransform X=\"-1\" Y=\"-1\" />
</Border.RenderTransform>
<Grid>
<Grid.Style>
<Style TargetType=\"Grid\">
<Style.Resources>
<ResourceDictionary />
</Style.Resources>
<Setter Property=\"Panel.Background\">
<Setter.Value>
<SolidColorBrush>#00FFFFFF</SolidColorBrush>
</Setter.Value>
</Setter>
</Style>
</Grid.Style>
<Label Content=\"{TemplateBinding ContentControl.Content}\" Background=\"#00FFFFFF\" Foreground=\"{TemplateBinding TextElement.Foreground}\" HorizontalContentAlignment=\"Center\" VerticalContentAlignment=\"Center\" Padding=\"{TemplateBinding Control.Padding}\" Style=\"{x:Null}\" Grid.Column=\"0\" Grid.Row=\"0\" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property=\"ButtonBase.IsPressed\">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<Storyboard.Children>
<DoubleAnimation To=\"0\" Duration=\"00:00:00\" Storyboard.TargetName=\"translation\" Storyboard.TargetProperty=\"(TranslateTransform.X)\" />
<DoubleAnimation To=\"0\" Duration=\"00:00:00\" Storyboard.TargetName=\"translation\" Storyboard.TargetProperty=\"(TranslateTransform.Y)\" />
</Storyboard.Children>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<Storyboard.Children>
<DoubleAnimation To=\"-1\" Duration=\"00:00:00\" Storyboard.TargetName=\"translation\" Storyboard.TargetProperty=\"(TranslateTransform.X)\" />
<DoubleAnimation To=\"-1\" Duration=\"00:00:00\" Storyboard.TargetName=\"translation\" Storyboard.TargetProperty=\"(TranslateTransform.Y)\" />
</Storyboard.Children>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
<Trigger.Value>
<s:Boolean>True</s:Boolean>
</Trigger.Value>
</Trigger>
<Trigger Property=\"UIElement.IsEnabled\">
<Setter Property=\"UIElement.Opacity\" TargetName=\"content\">
<Setter.Value>
<s:Double>0.5</s:Double>
</Setter.Value>
</Setter>
<Trigger.Value>
<s:Boolean>False</s:Boolean>
</Trigger.Value>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Please take a look at TranslateTransform in Border.RenderTransform. In the ResourceDictionary it has x:Name="translation", but the name is missing in the output string.
Where was I mistaken or is this a bug? Thanks in advance.
According to this MSDN blog post, "some markup extensions, such as {x:Static}, are resolved at load-time by XamlReader and the markup extension itself is discarded, so there is no means for XamlWriter to re-produce it." It looks like x:Name is one of those markup extensions that is lost.
It looks like you are trying to create two styles - an original and an extended one - that both implicitly target button (presumably in different scopes). If that is the case, you can create a base style in a resource both styles above can reference, then use Style's BasedOn property to keep from duplicating the template.

How to address children of a style ControlTemplate for animation?

I have a custom control extending a toggle button. This custom control has three dependency properties for ImageSources that can be used to customize Images that present a certain visual impression:
<Style TargetType="{x:Type local:SimpleFeedbackToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:SimpleFeedbackToggleButton}">
<Grid x:Name="BtnGrid">
<Image x:Name="FeedbackImage" Source="{TemplateBinding FeedbackImageSource}" Visibility="Hidden" />
<Image x:Name="NormalImage" Margin="{TemplateBinding Padding}" Source="{TemplateBinding NormalImageSource}" />
<Image x:Name="DisabledImage" Source="{TemplateBinding DisabledImageSource}" Visibility="Hidden" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Visibility" Value="Visible" TargetName="DisabledImage"/>
<Setter Property="Opacity" Value="1.0" TargetName="BtnGrid"/>
</Trigger>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Visibility" Value="Visible" TargetName="FeedbackImage"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding FeedbackBlink, RelativeSource={RelativeSource Self}}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard x:Name="SB_BlinkFeedback">
<Storyboard Storyboard.TargetProperty="Opacity">
<DoubleAnimation From="1.0" To="0.3" Duration="0:0:1" RepeatBehavior="Forever" AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="SB_BlinkFeedback" />
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
Another dependency property FeedbackBlink shall be used to start and stop blinking of only one of the images (FeedbackImage). Unfortunately I cannot find out how to address this image from the Storyboard "SB_BlinkFeedback". How could I do that?
Found a working solution shortly after posting the question: I had to move the DataTrigger from <Style.Triggers> to <ControlTemplate.Triggers>. Then the Storyboard declaration can be completed by Storyboard.TargetName="FeedbackImage" without compiler or runtime error.

Resources