Wpf Toolkit Chart Invert Highlighting - wpf

How can I highlight other pieces (columns, bars etc.) in a chart created with wpf toolkit. I am using a control template to style my own chart. So far I used a trigger to get a fading effect on the element on which the mouse is residing. I want to invert this; to fade other elements (a popular charting visual gimmick) on to which mouse is not pointing. Following image shows the selected column Faded, I want it to be the other way around.

Just set the default value to faded and use the trigger to bring it up to full opacity. You have done some other styling but here is an example based on the default style:
<Grid>
<Grid.Resources>
<PointCollection x:Key="sampleData">
<Point>1,20</Point>
<Point>2,40</Point>
<Point>3,30</Point>
</PointCollection>
<Style x:Key="dimEffectStyle" TargetType="{x:Type charting:ColumnDataPoint}" BasedOn="{StaticResource {x:Type charting:ColumnDataPoint}}">
<Setter Property="Opacity" Value="0.25"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.1" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="0.25" Duration="0:0:0.1" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<charting:Chart>
<charting:ColumnSeries
Title="A"
ItemsSource="{StaticResource sampleData}"
IndependentValueBinding="{Binding X}"
DependentValueBinding="{Binding Y}"
DataPointStyle="{StaticResource dimEffectStyle}"
/>
</charting:Chart>
</Grid>
Edit:
If you want to change all the other data points except the data point the mouse is over, that is a bit harder and can't be done simply by restyling the controls. But you can create your own series control that has that capability. Here is a chart with an unstyled column series class called MouseNotOverColumnSeries with a new MouseNotOverOpacity property:
<Grid.Resources>
<PointCollection x:Key="sampleData">
<Point>1,20</Point>
<Point>2,40</Point>
<Point>3,30</Point>
</PointCollection>
</Grid.Resources>
<charting:Chart Name="chart1">
<local:MouseNotOverColumnSeries
Title="A"
ItemsSource="{StaticResource sampleData}"
IndependentValueBinding="{Binding X}"
DependentValueBinding="{Binding Y}"
MouseNotOverOpacity="0.5"
/>
</charting:Chart>
Here is the MouseNotOverColumnSeries class:
public class MouseNotOverColumnSeries : ColumnSeries
{
public double MouseNotOverOpacity { get; set; }
protected override void OnDataPointsChanged(IList<DataPoint> newDataPoints, IList<DataPoint> oldDataPoints)
{
base.OnDataPointsChanged(newDataPoints, oldDataPoints);
foreach (var dataPoint in oldDataPoints)
{
dataPoint.MouseEnter -= new MouseEventHandler(dataPoint_MouseEnter);
dataPoint.MouseLeave -= new MouseEventHandler(dataPoint_MouseLeave);
}
foreach (var dataPoint in newDataPoints)
{
dataPoint.MouseEnter += new MouseEventHandler(dataPoint_MouseEnter);
dataPoint.MouseLeave += new MouseEventHandler(dataPoint_MouseLeave);
}
}
void dataPoint_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
{
foreach (var dataPoint in ActiveDataPoints)
if (e.OriginalSource != dataPoint) dataPoint.Opacity = MouseNotOverOpacity;
}
void dataPoint_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
{
foreach (var dataPoint in ActiveDataPoints)
dataPoint.Opacity = 1;
}
}
We just pay attention to when the data points change and register mouse enter/leave handlers that manipulate the opacity of all the other data points that the mouse is not over. This could be expanded to support storyboards, etc.

Related

WPF Change button style at runtime

I am trying to turn on or off a style at runtime using a Toggle Switch.
I have added the style to a resource dictionary but im not sure how to make some C# code to load or unload the resource. All of my buttons are using a dynamic resource of "PassiveGlowButton" and when i use a toggle switch i would like it to remove the "PassiveGlowButton" so its using the style of "GlowButton"
The code behind "GlowButton" This is the code i want to apply when the toggle is on. This is in App.Xaml under Application.resources, resourceDictionary:
<ResourceDictionary>
<Style x:Key="GlowButton" TargetType="{x:Type Button}"
BasedOn="{StaticResource AccentedSquareButtonStyle}">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="5" Color="WhiteSmoke" BlurRadius="18"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<EventTrigger RoutedEvent="Button.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="Effect.ShadowDepth"
From="3.0" To="0.0" Duration="0:0:1"
AutoReverse="True" RepeatBehavior="Forever"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<!-- Mouse over glow -->
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="Effect.BlurRadius"
From="45.0" To="17.0" Duration="0:0:1"
AutoReverse="True" RepeatBehavior="Forever"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="Effect.BlurRadius"
From="15.0" To="15.0" Duration="0:0:1"
AutoReverse="True" RepeatBehavior="Forever"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
Update
I have been able to set the style using a button but it will only apply to a button called Testbttn. Is there a way to change it to apply to Button.Style? If i use this method it also looses the storyboard of the button for some reason
Style style = this.FindResource("PassiveGlowButton") as Style;
TestBttn.Style = style;
Update 2: The solution was to create 3 styles, one the button uses from load and then 2 others, one with a blank button and one with the style i wanted.
I have attached the code i used to swap between the styles.
private void ButtonStyle_Checked(object sender, RoutedEventArgs e)
{
Application.Current.Resources["PassiveGlowButton"] = Application.Current.Resources["PassiveGlowButtonOn"];
}
private void ButtonStyle_UnChecked(object sender, RoutedEventArgs e)
{
Application.Current.Resources["PassiveGlowButton"] = Application.Current.Resources["PassiveGlowButtonOff"];
}
There are several ways of doing this.
What you're asking may be best redesigned to use VisualStateManager.
Another option is redesigning the styles into a StyleViewModel. (I recommend using a enum and typing your styles so that the VM can live / reference separate from the styles themselves) If you do this properly you can change the style type and the styles binding will update.
Finally you can use DynamicResource as the style and make a default style resource that's set else where. Styles, when used as a resource, can have the same key in separate dictionaries. The names overlapped so the last one in (or closest to the control requesting it in the hierarchy) will be the one to get used. You can re-arrange the style order or add / remove them but the controls won't update until the next time they are loaded.
Each is a little tricky to implement and although I like VisualStateManager I'm a fan of the binding fix (option 2) myself. There's a difference between the two; so I don't want this to confuse you or start a debate. I'm just illustrating options.
Here's a quick example of binding styles if you do prefer to go that route which will fix your problem IMO.
Example:
Styles
<Application x:Class="Question_Answer_WPF_App.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style x:Key="StyleA"
TargetType="Button">
<Setter Property="Background"
Value="Green" />
<Setter Property="Height"
Value="40" />
<Setter Property="Margin"
Value="4" />
</Style>
<Style x:Key="StyleB"
TargetType="Button">
<Setter Property="Background"
Value="Blue" />
<Setter Property="Height"
Value="30" />
</Style>
</Application.Resources>
</Application>
Enum
namespace Question_Answer_WPF_App.ViewModels
{
public enum Styles
{
StyleA,
StyleB
}
}
ViewModel
using System.Windows.Input;
namespace Question_Answer_WPF_App.ViewModels
{
public class StylesViewModel : NotifyModel
{
private Styles selectedStyle;
public StylesViewModel()
{
SelectStyleCommand = new RelayCommand(SelectStyle);
}
public Styles SelectedStyle
{
get { return selectedStyle; }
set
{
selectedStyle = value;
Notify();
}
}
public ICommand SelectStyleCommand { get; }
private void SelectStyle(object obj)
{
if (obj is Styles style) SelectedStyle = style;
}
}
}
Converter
using Question_Answer_WPF_App.ViewModels;
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
namespace Question_Answer_WPF_App.Views
{
public class StyleTypeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var result = Application.Current.Resources["StyleA"];
if (value is Styles style)
{
switch (style)
{
case Styles.StyleB:
result = Application.Current.Resources["StyleB"];
break;
case Styles.StyleA:
default:
result = Application.Current.Resources["StyleA"];
break;
}
}
return result;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
=> DependencyProperty.UnsetValue;
}
}
View
<UserControl x:Class="Question_Answer_WPF_App.Views.StylesTestView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ViewModels="clr-namespace:Question_Answer_WPF_App.ViewModels"
xmlns:local="clr-namespace:Question_Answer_WPF_App.Views">
<UserControl.Resources>
<ViewModels:StylesViewModel x:Key="StylesViewModel" />
<local:StyleTypeConverter x:Key="StyleTypeConverter" />
</UserControl.Resources>
<StackPanel>
<Button Style="{Binding SelectedStyle, Source={StaticResource StylesViewModel}, Converter={StaticResource StyleTypeConverter}}"
Command="{Binding SelectStyleCommand, Source={StaticResource StylesViewModel}}"
CommandParameter="{x:Static ViewModels:Styles.StyleA}"
Content="Select Style A" />
<Button Style="{Binding SelectedStyle, Source={StaticResource StylesViewModel}, Converter={StaticResource StyleTypeConverter}}"
Command="{Binding SelectStyleCommand, Source={StaticResource StylesViewModel}}"
CommandParameter="{x:Static ViewModels:Styles.StyleB}"
Content="Select Style B" />
</StackPanel>
</UserControl>
Results

Making a WPF Label (or other element) flash using animation

I have a label that I only make visible based on one of my ViewModel Properties. Here is the XAML:
<Label HorizontalAlignment="Center" VerticalAlignment="Center"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
FontSize="24" Width="200" Height="200" >
<Label.Content >
Option in the money!
</Label.Content>
<Label.Style>
<Style TargetType="{x:Type Label}">
<Setter Property="Visibility" Value="Hidden" />
<Style.Triggers>
<DataTrigger Binding="{Binding OptionInMoney}" Value="True">
<Setter Property="Visibility"
Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Label.Style>
</Label>
I'm not sure this is the best way, but in any case, I'd also like to have the label flashing. Clearly, I only want it flashing when it is visible. Can someone point me to some example code, or write a quick example to do this? I assume I need some sort of trigger, and an animation. Presumably I also need a trigger when the label is no longer visible so that I stop the animation?
Thanks,
Dave
P.S. Is there a good book or site for all these WPF tricks? Something like the "MFC Answer Book" for those that remember that book.
You could add a Storyboard animation to the Style.Resources and start it in the EnterActions section of the DataTrigger.
A simple DoubleAnimation on the Opacity should work fine
Something like this:
<Label.Style>
<Style TargetType="{x:Type Label}">
<Style.Resources>
<Storyboard x:Key="flashAnimation" >
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="1" To="0" AutoReverse="True" Duration="0:0:0.5" RepeatBehavior="Forever" />
</Storyboard>
</Style.Resources>
<Setter Property="Visibility" Value="Hidden" />
<Style.Triggers>
<DataTrigger Binding="{Binding OptionInMoney}" Value="True">
<Setter Property="Visibility" Value="Visible" />
<DataTrigger.EnterActions>
<BeginStoryboard Name="flash" Storyboard="{StaticResource flashAnimation}" />
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="flash"/>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Label.Style>
StoryBoard is certainly the WPF way, but it can be achieved by a simple code also. Here it goes, to make a label background blink:
lblTimer is a Lebel on your form with some text, say, "I AM BLINKING"
This can be applied to any property, as VISIBILITY.
// Create a timer.
private void Window_Loaded(object sender, RoutedEventArgs e)
{
DispatcherTimer timer = new DispatcherTimer();
timer.Tick += timer_Tick;
timer.Interval = new TimeSpan(0, 0, 0, 0, 500);
timer.Start();
}
// The timer's Tick event.
private bool BlinkOn = false;
private void timer_Tick(object sender, EventArgs e)
{
if (BlinkOn)
{
lblTimer.Foreground = Brushes.Black;
lblTimer.Background = Brushes.White;
}
else
{
lblTimer.Foreground = Brushes.White;
lblTimer.Background = Brushes.Black;
}
BlinkOn = !BlinkOn;
}
Try this post. It's called 'Blinking TextBlock' but you can easily swap a TextBox for a Label`.

Border Color animation in WPF not working in "real-time"

In WPF app I am trying to animate a border colour change on MouseEnter event of a TextBox.
I searched for a while and followed different tutorials, but everything seems to end up the same way:
When the mouse enters the colour of the border changes to what I have set in the animation "From"
Then nothing happens, no animation at all
When mouse leaves after a period longer then the animation duration the colour changes to what I have set in the animation "To"
If the mouse leaves before the animation duration, the colour of the border changes to some colour "in between"
From this I figured that the animation is happening, but it is not showing it as it animates...
The code is here:
private void txtSpeakMe_MouseEnter(object sender, MouseEventArgs e)
{
ColorAnimation ca = new ColorAnimation();
ca.From = (Color)ColorConverter.ConvertFromString("#0066FF");
ca.To = (Color)ColorConverter.ConvertFromString("#FF0000");
ca.Duration = TimeSpan.FromSeconds(3);
txtSpeakMe.BorderBrush.BeginAnimation(SolidColorBrush.ColorProperty, ca);
}
Any ideas on why it is not showing the animation as it is happening? I tried animation in XAML using MS tutorials, the same effect - it animates but it is not showing the process of animation until mouse leaves...
It may be easier to use a Trigger in the Xaml to perform this animation, Triggers have a EnterActions and ExitActions so you could use the IsMouseOver event to start/stop the animation
Example:
<Border Name="border" BorderThickness="5" Width="200" Height="30">
<TextBox Text="StackOverflow"/>
<Border.Style>
<Style TargetType="Border">
<Setter Property="BorderBrush" Value="#0066FF" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard HandoffBehavior="SnapshotAndReplace">
<Storyboard>
<ColorAnimation Duration="0:0:3" To="#FF0000" Storyboard.TargetProperty="BorderBrush.Color" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard HandoffBehavior="SnapshotAndReplace">
<Storyboard>
<ColorAnimation Duration="0:0:3" To="#0066FF" Storyboard.TargetProperty="BorderBrush.Color" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
Not sure why TextBox border color is not changing, but you could try this:
<Border Name = "border" BorderThickness="5">
<TextBox MouseEnter="TextBox_MouseEnter" MouseLeave="TextBox_MouseLeave"/>
</Border>
Then try this code on MouseEnter and MaouseLeave:
ColorAnimation ca = new ColorAnimation();
ca.From = (Color)ColorConverter.ConvertFromString("#0066FF");
ca.To = (Color)ColorConverter.ConvertFromString("#FF0000");
ca.Duration = TimeSpan.FromSeconds(3);
Storyboard sb = new Storyboard();
sb.Children.Add(ca);
Storyboard.SetTarget(ca, border);
Storyboard.SetTargetProperty(ca, new PropertyPath("(Border.BorderBrush).(SolidColorBrush.Color)"));
sb.Begin();

Trying to animate height but getting error that height is NaN

Been trying to create an animation to dynamically adjust height. I found this info that helped but when I try to use it I get an error: 'System.Windows.Media.Animation.DoubleAnimation' cannot use default destination value of 'NaN'.
If I specify the height I get that error.
Style:
<Style x:Key="bdrSlideIn"
TargetType="{x:Type Border}">
<Style.Resources>
<Storyboard x:Key="storyBoardIn">
<DoubleAnimation BeginTime="00:00:00"
From="0"
Duration="00:00:00.65"
Storyboard.TargetName="{x:Null}"
Storyboard.TargetProperty="(FrameworkElement.Height)"
DecelerationRatio="1" />
</Storyboard>
<Storyboard x:Key="storyBoardOut">
<DoubleAnimation BeginTime="00:00:00"
To="0"
Duration="00:00:00.65"
Storyboard.TargetName="{x:Null}"
Storyboard.TargetProperty="(FrameworkElement.Height)"
AccelerationRatio="1" />
</Storyboard>
</Style.Resources>
<Style.Triggers>
<DataTrigger Binding="{Binding SearchExecuted}"
Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource storyBoardIn}"
Name="SlideStoryboard" />
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource storyBoardOut}" />
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
Border:
<Border VerticalAlignment="Top"
Style="{StaticResource bdrSlideIn}">
<WPFToolKit:DataGrid Name="dgSearchResults"
ItemsSource="{Binding SearchResults}"
MaxHeight="280"
VerticalAlignment="Top">...
If you want to keep Height dynamic then you can't animate Height directly: As you've seen, unless you explicitly assign it WPF will try to interpolate to NaN.Instead, give your element a LayoutTransform <ScaleTransform/>, and animate the ScaleX and ScaleY parameters of that transformation.
You could always create an attached property for the height that does nothing other than set the height property on the target control, that way you can animate using To on your attached property.
public class AnimatedPanelBehavior
{
public static double GetAnimatedHeight(DependencyObject obj)
{
return (double)obj.GetValue(AnimatedHeightProperty);
}
public static void SetAnimatedHeight(DependencyObject obj, double value)
{
obj.SetValue(AnimatedHeightProperty, value);
}
public static readonly DependencyProperty AnimatedHeightProperty =
DependencyProperty.RegisterAttached("AnimatedHeight", typeof(double), typeof(AnimatedPanelBehavior), new UIPropertyMetadata(0d, new PropertyChangedCallback((s, e) =>
{
FrameworkElement sender = s as FrameworkElement;
sender.Height = (double)e.NewValue;
})));
}
Then to animate it you would use a normal animation, just tried it now and it works fine but I've not investigated any further than "it works".
<DoubleAnimation Storyboard.TargetProperty="(local:AnimatedPanelBehavior.AnimatedHeight)" To="100" Duration="0:0:5"/>
use AnimatedHeight instead of height on anything that you want to be able to animate.
Since your TargetProperty is Height, you can just set a default value of Height and it will work. In my case as soon as I have put a number for Height on the actual control itself,
<TextBlock Height="30" ..
<TextBlock Style ..
...
<StoryBoard ..
and then had the animation (which were to make toggle the height) it worked fine.

WPF - Confusing DataTrigger/DoubleAnimation behaviour

I'm trying to animate the ScaleY property of a LayoutTransform based on a DataTrigger bound to a boolean on my ViewModel class. The animation happens when the value is first seen to be false by the DataTrigger (when the application first starts) and when i first change it to true in a checkbox's checked event but not when i set it to false in the same checkbox's unchecked event.
A simplified version of what i'm doing is listed below.
The ViewModel class is very simple, containing a single boolean DependencyProperty called Selected.
public class VM : DependencyObject
{
public bool Selected
{
get { return (bool)GetValue(SelectedProperty); }
set { SetValue(SelectedProperty, value); }
}
// Using a DependencyProperty as the backing store for Selected. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SelectedProperty =
DependencyProperty.Register("Selected", typeof(bool), typeof(VM), new UIPropertyMetadata(false));
}
The Window.xaml contains a button and a checkbox. When the checkbox is checked, i set the ViewModel's 'Selected' property to true and false when it is unchecked. Here's the code for both the xaml and it's code-behind.
<Window x:Class="DataTriggers.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:y="clr-namespace:DataTriggers"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<y:VM x:Key="VM"/>
<Style TargetType="Button" x:Key="but">
<Style.Triggers>
<DataTrigger Binding="{Binding Selected}" Value="False">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:1"
To="0"
Storyboard.TargetProperty="(LayoutTransform).(ScaleTransform.ScaleY)"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
<DataTrigger Binding="{Binding Selected}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:1"
To="1"
Storyboard.TargetProperty="(LayoutTransform).(ScaleTransform.ScaleY)"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<StackPanel>
<Button Style="{StaticResource but}" DataContext="{StaticResource VM}">
<Button.LayoutTransform>
<ScaleTransform></ScaleTransform>
</Button.LayoutTransform>
me
</Button>
<CheckBox Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked"/>
</StackPanel>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void CheckBox_Checked(object sender, RoutedEventArgs e)
{
VM vm = this.FindResource("VM") as VM;
vm.Selected = true;
}
private void CheckBox_Unchecked(object sender, RoutedEventArgs e)
{
VM vm = this.FindResource("VM") as VM;
vm.Selected = false;
}
}
I know that the DataTrigger fires when the property is false because if i change the DoubleAnimation to a simple Setter operating on the Opacity property then i see the correct results. So it would seem to be a problem with how I'm using the DoubleAnimation.
Any help would be appriciated.
This is ODD behavior but i decided to refactor the 'False' case into the DataTrigger's ExitActions like this -
<DataTrigger Binding="{Binding Selected}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:1"
To="1"
Storyboard.TargetProperty="(RenderTransform).(ScaleTransform.ScaleY)"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:1"
To="0"
Storyboard.TargetProperty="(RenderTransform).(ScaleTransform.ScaleY)"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
That works as intended. I don't know what the difference is between the two cases but at least it's an answer.

Resources