DoubleAnimation exception when animating grid width with DataTrigger - wpf

I'm trying to animate a grid's width upon a toggle button being checked. I've used a data trigger in the Grid's style element to do this, however, whenever it's triggered I get an error, stating:
Cannot animate the 'Width' property on a
'System.Windows.Controls.Grid' using a
'System.Windows.Media.Animation.DoubleAnimation'
I'm pretty sure it is possible to animate the grid in the way I'm attempting, as I've gotten it to work using a click event. Does anyone see where I'm going wrong here?
<Grid Margin="0" HorizontalAlignment="Left"
TextOptions.TextFormattingMode="Display" x:Name="MainGrid" >
<Grid.Resources>
<Style TargetType="Grid">
<Style.Setters>
<Setter Property="Width" Value="300"/>
</Style.Setters>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsChecked, ElementName=CollapseIcon}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard >
<Storyboard >
<DoubleAnimation Duration="0:0:0.200" Storyboard.TargetProperty="Width" To="16" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Resources>

I apologize man, I completely forgot to get back to this Friday and then saw your question again today. Anyway you're so close! Move your dependency property for Width to the object and you're all done! This tested just fine on my end. Cheers!
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid Margin="0" HorizontalAlignment="Left" Width="300" Background="Red"
TextOptions.TextFormattingMode="Display" x:Name="MainGrid" >
<Grid.Resources>
<Style TargetType="Grid">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsChecked, ElementName=CollapseIcon}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard >
<Storyboard >
<DoubleAnimation Duration="0:0:0.2"
Storyboard.TargetProperty="Width"
From="300" To="16" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Resources>
</Grid>
<ToggleButton x:Name="CollapseIcon" Content="Magic!" Height="50" Width="50"/>
</Grid>
</Window>
ADDENDUM: Forgot in a DoubleAnim you need to be explicit with both To AND FROM or it just returns NaN in the From by default. Cheers!

Related

How to use style in xaml to move an ellipse on canvas

I'm practicing using xaml styles by making a simple traffic light controlled by radiobuttons. However, my code crashes because there is a reference error using Canvas.Top in the Ellipse style. Is there any way I could fix that while keeping everything in the style and not in the Ellipse itself?
Here is my code:
<Window x:Class="hw05.MainWindow"
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"
xmlns:local="clr-namespace:hw05"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<Style TargetType="Ellipse">
<Setter Property="Fill" Value="Red"></Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, ElementName=RedRB}" Value="True">
<Setter Property="Fill" Value="Red"></Setter>
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="Canvas.Top" Duration="0:0:0.400" To="83">
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
<DataTrigger Binding="{Binding IsChecked, ElementName=YellowRB}" Value="True">
<Setter Property="Fill" Value="Orange"></Setter>
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="Canvas.Top" Duration="0:0:0.400" To="133">
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
<DataTrigger Binding="{Binding IsChecked, ElementName=GreenRB}" Value="True">
<Setter Property="Fill" Value="Green"></Setter>
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="Canvas.Top" Duration="0:0:0.400" To="183">
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Canvas>
<RadioButton Name="RedRB" GroupName="One" IsChecked="True" Canvas.Left="50" Canvas.Top="100">first</RadioButton>
<RadioButton Name="YellowRB" GroupName="One" IsChecked="False" Canvas.Left="50" Canvas.Top="150">second</RadioButton>
<RadioButton Name="GreenRB" GroupName="One" IsChecked="False" Canvas.Left="50" Canvas.Top="200">third</RadioButton>
<Ellipse Name="Light" Width="50" Height="50" Canvas.Left="180"></Ellipse>
</Canvas>
</Window>
EDIT included setter for a Canvas.Top value and used parentheses for (Canvas.Top):
<Window x:Class="hw05.MainWindow"
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"
xmlns:local="clr-namespace:hw05"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<Style TargetType="Ellipse">
<Setter Property="Fill" Value="Red"></Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, ElementName=RedRB}" Value="True">
<Setter Property="Fill" Value="Red"></Setter>
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="(Canvas.Top)" Duration="0:0:0.400" To="83">
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
<DataTrigger Binding="{Binding IsChecked, ElementName=YellowRB}" Value="True">
<Setter Property="Fill" Value="Orange"></Setter>
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="(Canvas.Top)" Duration="0:0:0.400" To="133">
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
<DataTrigger Binding="{Binding IsChecked, ElementName=GreenRB}" Value="True">
<Setter Property="Fill" Value="Green"></Setter>
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="(Canvas.Top)" Duration="0:0:0.400" To="183">
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Canvas>
<RadioButton Name="RedRB" GroupName="One" IsChecked="True" Canvas.Left="50" Canvas.Top="100">first</RadioButton>
<RadioButton Name="YellowRB" GroupName="One" IsChecked="False" Canvas.Left="50" Canvas.Top="150">second</RadioButton>
<RadioButton Name="GreenRB" GroupName="One" IsChecked="False" Canvas.Left="50" Canvas.Top="200">third</RadioButton>
<Ellipse Name="Light" Width="50" Height="50" Canvas.Left="180" Canvas.Top="82"></Ellipse>
</Canvas>
</Window>
Canvas.Top is an attached property so you should add parentheses around it:
Storyboard.TargetProperty="(Canvas.Top)"
You should also set the From property of the DoubleAnimation to a valid double such as for example 0:
<DoubleAnimation
Storyboard.TargetProperty="(Canvas.Top)" Duration="0:0:0.400" From="0" To="133">
Alternatively, you could set the Canvas.Top property of the element being animated to an initial value:
<Ellipse Name="Light" Width="50" Height="50" Canvas.Top="10" Canvas.Left="180"></Ellipse>
Or add a Setter to the Style:
<Setter Property="Canvas.Top" Value="10"/>
When you animate a property without setting the animation's From property, the animation starts from the current value of the property.
For Canvas.Top and the other Canvas attached properties, the default value (and hence the current value) is double.NaN, not 0.
Just set an initial value by a Style Setter:
<Style TargetType="Ellipse">
<Setter Property="Canvas.Top" Value="0"/>
...
</Style>
Or directly on the Ellipse:
<Ellipse Canvas.Top="0" .../>
You would also need to use the correct animated property path for attached properties, which uses parentheses:
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Top)" .../>

Open Popup with delay when clicking cell

I want to show a popup with delay 2 seconds always when any cell of a column is selected and the cursor stays longer than 2 seconds. I could implement that with timers and eventhandlers but I think,I can also achieve that with storyboards. I try to do that so:
<Window x:Class="Wpfpopupstoryboard.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<Storyboard x:Key="ShowPopup">
<BooleanAnimationUsingKeyFrames Storyboard.TargetName="LockPopup" Storyboard.TargetProperty="(Popup.IsOpen)">
<DiscreteBooleanKeyFrame KeyTime="00:00:02.0" Value="True" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="HidePopup" Storyboard.TargetName="LockPopup" Storyboard.TargetProperty="(Popup.IsOpen)">
<BooleanAnimationUsingKeyFrames>
<DiscreteBooleanKeyFrame KeyTime="00:00:00.1" Value="False" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<DataGrid Name="MyGrid" xmlns:sys="clr-namespace:System;assembly=mscorlib" IsReadOnly="True">
<DataGrid.Resources>
<Style TargetType="DataGridCell">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DataGridCell">
<StackPanel>
<Border x:Name="border"
BorderThickness="2"
BorderBrush="Silver">
<ContentPresenter Name="MyContentPresenter" Content="{Binding}"/>
</Border>
<Popup x:Name="LockPopup" PlacementTarget="{Binding ElementName=MyContentPresenter}" Placement="Bottom" DataContext="{Binding}">
<TextBlock Text="This is a popup" Background="White" Foreground="Black" />
</Popup>
</StackPanel>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="StackPanel.MouseLeftButtonDown">
<BeginStoryboard Storyboard="{StaticResource ShowPopup}"/>
</EventTrigger>
<EventTrigger RoutedEvent="StackPanel.MouseLeave">
<BeginStoryboard Storyboard="{StaticResource HidePopup}"/>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding}" Header="column" />
</DataGrid.Columns>
<sys:String>item 1</sys:String>
<sys:String>item 2</sys:String>
<sys:String>item 3</sys:String>
<sys:String>item 4</sys:String>
</DataGrid>
</Grid>
What is wrong? Can somebody help me?
Thank you!
With using RemoveStoryboard action, you need just 1 Storyboard (to show the popup). Also the right event to trigger the Storyboard here is Selected instead of StackPanel.MouseLeftButtonDown:
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="Selected">
<BeginStoryboard Storyboard="{StaticResource ShowPopup}" Name="bg"/>
</EventTrigger>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard Storyboard="{StaticResource ShowPopup}" Name="bg2"/>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<RemoveStoryboard BeginStoryboardName="bg"/>
</EventTrigger>
</ControlTemplate.Triggers>
You can delete the HidePopup Storyboard, because we don't need it with the code above.
In fact you can also use StackPanel.PreviewMouseLeftButtonDown, somehow the StackPanel.MouseLeftButtonDown is suppressed (while bubbling up from the inner elements). However it's just a bit explanation about why it's not working at first. Using the Selected event is the best choice.
MouseLeftButtonDown event have a Direct Routing strategy (see UIElement.MouseLeftButtonDown Event (msdn)).
So it will not bubble to your ContentTemplate.
You need to set the event trigger on your StackPanel directly.

Specifying PropertyPath syntax for animation inside GroupStyle.HeaderTemplate

I'm trying to perform a rotate animation inside a GroupStyle header on a DataGrid and I cannot get the PropertyPath syntax down for the Storyboard.TargetProperty property. Here's a contained example to highlight my problem
<Window x:Class="ImageRotateTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<x:Array Type="sys:String">
<sys:String>One</sys:String>
<sys:String>One</sys:String>
<sys:String>Three</sys:String>
<sys:String>Four</sys:String>
<sys:String>Four</sys:String>
</x:Array>
</Window.DataContext>
<Window.Resources>
<CollectionViewSource Source="{Binding}" x:Key="ViewSource">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription></PropertyGroupDescription>
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</Window.Resources>
<DataGrid ItemsSource="{Binding Source={StaticResource ViewSource}}" AutoGenerateColumns="False">
<DataGrid.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}">
<TextBlock.RenderTransform>
<RotateTransform/>
</TextBlock.RenderTransform>
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding Name}" Value="Three">
<DataTrigger.EnterActions>
<BeginStoryboard x:Name="Test">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="RenderTransform.Angle" To="360" Duration="0:0:0.800" RepeatBehavior="Forever"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="Test" />
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</DataGrid.GroupStyle>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding}" Header="Item" />
</DataGrid.Columns>
</DataGrid>
The result here should be that the group header should spin only for the "Three" group and not any others. However, running this results in the following exception
A first chance exception of type 'System.Windows.Markup.XamlParseException' occurred in PresentationFramework.dll
Additional information: Cannot resolve all property references in the property path 'RenderTransform.Angle'. Verify that applicable objects support the properties.
I have tried the following for the Storyboard.TargetProperty without success
(TextBlock.RenderTransform).(RotateTransform.Angle)
(RenderTransform).(Angle)
RenderTransform.Angle
My question is; How can I refer to the TextBlock.RenderTransform using property path syntax?
Your code very nearly works as it is. You just need to make one change:
Storyboard.TargetProperty="RenderTransform.(RotateTransform.Angle)"
I have tested it with just the TextBlock and can see that spinning away, so if you can't see it spinning in your DataGrid, either your Name property Binding is incorrect, or its value is not the expected "Three".
<TextBlock Text="{Binding Name}">
<TextBlock.RenderTransform>
<RotateTransform/>
</TextBlock.RenderTransform>
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding Name}" Value="Three">
<DataTrigger.EnterActions>
<BeginStoryboard x:Name="Test">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="
RenderTransform.(RotateTransform.Angle)" To="360"
Duration="0:0:0.800" RepeatBehavior="Forever"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="Test" />
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
For Rotation of Object this is simple and best example..
<Window x:Class="Animation.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Animated Rectangle" Height="350" Width="525">
<Grid>
<StackPanel Margin="10">
<Image Name="MyImage" Source="e:\a.jpg" Width="100" Margin="50" ></Image>
<Rectangle
Name="MyRectangle"
Width="100"
Height="100"
Fill="Blue">
<Rectangle.Triggers>
<!-- Animates the rectangle's opacity. -->
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="MyImage"
Storyboard.TargetProperty="Opacity"
From="1.0" To="0.0" Duration="0:0:3"
AutoReverse="True" RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</StackPanel>
</Grid>

Best practice to pipe WPF animation trigger from one ControlTemplate element to another

After reading several SO posts (here, here, and here) I still can't find any way to solve my problem... Basically, I redefined Button layout, and packed it up in a style. The new Button ControlTemplate contains a Rectangle I want to animate on Button click. Which TargetProperty do I have to use in my animation? Following is what I done :
UserControl x:Class="OfficeTourismeBrantome.Views.MainMenuView"
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="800" d:DesignWidth="300">
<UserControl.Resources>
<Style x:Key="MenuItemButtonStyle" TargetType="Button">
<Setter Property="FontSize" Value="35" />
<Setter Property="FontFamily" Value="Segoe" />
<Setter Property="Foreground" Value="#FFEBEDEA" />
<!--<Setter Property="Height" Value="{Binding MenuLayout.MenuItemSize.Height}" />-->
<Setter Property="HorizontalContentAlignment" Value="Right" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Canvas HorizontalAlignment="Stretch">
<ContentPresenter Canvas.Left="{Binding MenuLayout.MenuItemLeftMargin}" HorizontalAlignment="Center"
VerticalAlignment="Center"/>
<Rectangle
Name="test"
Width="0"
Height="3"
Fill="Aqua"/>
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
<!-- Which targetProperty should I use to animate ControlTemplate Rectangle ?-->
From="0.0"
To="10.0"
Duration="0:0:2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
<ItemsControl Name="menuButtonContainer" ItemsSource="{Binding Items}" Margin="{Binding MenuLayout.MenuMargin}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button
Style="{StaticResource ResourceKey=MenuItemButtonStyle}"
Margin="{Binding ElementName=menuButtonContainer,
Path=DataContext.MenuLayout.MenuItemMargin}"
Height="{Binding ElementName=menuButtonContainer,
Path=DataContext.MenuLayout.MenuItemSize.Height}"
Content="{Binding Text}"
Command="{Binding ElementName=menuButtonContainer,
Path=DataContext.ChangeThemeCommand}"
CommandParameter="{Binding Id}"
/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
I may be wrong in my implementation, still trying to understand WPF subtilities... What's the best way to achieve my goal?
Many thanks for your answers !
Which target property you want to animate is the question you have to ask yourself ! Do you want to change the rectangle's Width ? Its Opacity ? ...
Best practice... I don't know, but that's one way to do it :
<ControlTemplate TargetType="Button">
[...]
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard TargetName="test" TargetProperty="Width">
<DoubleAnimation From="0.0" To="10.0" Duration="0:0:2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</ControlTemplate.Triggers>

Storyboard not found in name scope of style

The problem I'm having is that if I base a style on a second style that contains a storyboard, then there is an exception in the Trigger.ExitAction.
If I mouse over either of the rectangles in the demo below then the storyboard will run and the rectangles change colour.
When the mouse leaves the red rectangle with style='rectStyle' the storyboard is removed.
When the mouse leaves the blue rectangle (which uses the derived style) I get this exception:
InvalidOperationException:
'MouseOverStoryboard' name cannot be found in the name scope of 'System.Windows.Style'.
So:
Is it valid to have a storyboard in a base style?
Is there a more explicit way of referring to the BeginStoryboardName so that this error doesn't occur?
Any other suggestions?
In the end what I'm trying to achieve re-use a style containing triggers and storyboards in several other styles.
Here's some simple code that demonstrates the problem:
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.Resources>
<Style x:Key="rectStyle" TargetType="{x:Type Rectangle}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard x:Name="MouseOverStoryboard">
<Storyboard>
<ColorAnimation To="PaleGoldenrod"
Storyboard.TargetProperty="(Fill).(Color)"
Duration="0:0:1"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="MouseOverStoryboard"/>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="rectStyle2" TargetType="{x:Type Rectangle}"
BasedOn="{StaticResource rectStyle}"/>
</Grid.Resources>
<Rectangle Grid.Row="0" Width="100" Height="100" Fill="Red"
Style="{StaticResource rectStyle}" />
<Rectangle Grid.Row="1" Width="100" Height="100" Fill="Blue"
Style="{StaticResource rectStyle2}" />
</Grid>
Your best bet is to steer clear of derived styles if you want to include StopStoryboard. There are actually 2 instances of the style and the scope is wrong for the derived style. I believe this is by design. You could abstract that storyboard out to an outer scope in the resources and duplicate the triggers in both styles, referencing the Storyboard by StaticResource. It may not solve your problem since you may have a specific requirement for derived styles, but I don't think you have a choice unfortunately.
Because you cannot inherit from a base style at all if you want to use StopStoryboard you'd have to do something like this:
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.Resources>
<Storyboard x:Key="mouseOver">
<ColorAnimation
AutoReverse="True"
Duration="0:0:1"
RepeatBehavior="Forever"
Storyboard.TargetProperty="(Fill).(Color)"
To="PaleGoldenrod"/>
</Storyboard>
<Style x:Key="rectStyle" TargetType="{x:Type Rectangle}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard x:Name="MouseOverStoryboard" Storyboard="{StaticResource mouseOver}"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="MouseOverStoryboard"/>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="rectStyle2" TargetType="{x:Type Rectangle}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard x:Name="MouseOverStoryboard1" Storyboard="{StaticResource mouseOver}"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="MouseOverStoryboard1"/>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<Rectangle
Width="100"
Height="100"
Grid.Row="0"
Fill="Red"
Style="{StaticResource rectStyle}"/>
<Rectangle
Width="100"
Height="100"
Grid.Row="1"
Fill="Blue"
Style="{StaticResource rectStyle2}"/>
Just stumbled upon this due to having the same problem. There is another solution, albeit a somewhat clunky one.
Animations on Properties get overwritten when applying another animation, so you can use another BeginStoryboard in the ExitActions of the Trigger to overwrite the previous one, and use a FillBehavior of Stop to automatically remove that.
Unfortunately, the combination of Duration=0, FillBehavior=Stop, and no target value doesn't work, so you need to set a very short duration for that animation.
In your example:
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.Resources>
<Style x:Key="rectStyle" TargetType="{x:Type Rectangle}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation To="PaleGoldenrod"
Storyboard.TargetProperty="(Fill).(Color)"
Duration="0:0:1"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard FillBehavior="Stop">
<ColorAnimation
Storyboard.TargetProperty="(Fill).(Color)"
Duration="0:0:0.0000001"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="rectStyle2" TargetType="{x:Type Rectangle}"
BasedOn="{StaticResource rectStyle}"/>
</Grid.Resources>
<Rectangle Grid.Row="0" Width="100" Height="100" Fill="Red"
Style="{StaticResource rectStyle}" />
<Rectangle Grid.Row="1" Width="100" Height="100" Fill="Blue"
Style="{StaticResource rectStyle2}" />
</Grid>

Resources