I've just started to learn WPF and now I'm doing my second WPF application with C# and .NET Framework 4.7.
I want to fire an animation when Label's Content changes. I have 81 labels on my View and I want to associate the same animation to all of them.
This is one of my labels, but all of them are mostly identical:
<Label x:Name="c00" Content="{Binding BestIndividual[0]}" Margin="0" BorderThickness="2,2,0,0" BorderBrush="Black" />
Searching, I have found this solution, but I don't know how to applied to what I need.
I think I have found how to do it in this article: How to: Trigger an Animation When a Property Value Changes.
But, who can I fire a trigger when Label's Content change?
The only way that I've found about how to fire a trigger is when a property has a value:
<Trigger Property="IsMouseOver" Value="True">
EventTriggers are meant for executing actions - animation included - in response to a routed event.
As mm8 suggested, the Label
control has no "ContentChanged" event. But instead of using a normal event, you can implement a routed one:
public class CustomLabel : Label
{
public static readonly RoutedEvent ContentChangedEvent = EventManager.RegisterRoutedEvent(
"ContentChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(CustomLabel));
public event RoutedEventHandler ContentChanged
{
add
{
AddHandler(ContentChangedEvent, value);
}
remove
{
RemoveHandler(ContentChangedEvent, value);
}
}
protected override void OnContentChanged(object oldContent, object newContent)
{
base.OnContentChanged(oldContent, newContent);
RaiseEvent(new RoutedEventArgs(ContentChangedEvent));
}
}
In this way you can create a Style
with an EventTrigger
for beginning an animation:
<Style x:Key="ContentChangedAnimated" TargetType="{x:Type local:CustomLabel}"
BasedOn="{StaticResource {x:Type Label}}">
<Style.Triggers>
<EventTrigger RoutedEvent="ContentChanged">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:2" Storyboard.TargetProperty="FontSize"
To="28" AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
Then you need to apply that style to your (Custom)Labels:
<local:CustomLabel x:Name="c00" Content="{Binding BestIndividual[0]}" Margin="0" Style="{StaticResource ContentChangedAnimated}"
BorderThickness="2,2,0,0" BorderBrush="Black" />
I hope it can help you.
The Label
class has no "ContentChanged" event but you could define your own custom Label
class and override the OnContentChanged
method:
public class CustomLabel : Label
{
public event EventHandler ContentChanged;
protected override void OnContentChanged(object oldContent, object newContent)
{
base.OnContentChanged(oldContent, newContent);
if (ContentChanged != null)
ContentChanged(this, EventArgs.Empty);
}
}
In the XAML you replace all Label
elements with your custom type:
<local:CustomLabel x:Name="c00" Content="{Binding BestIndividual[0]}" ContentChanged="OnContentChanged" />
You could then perform the animation programmatically in the event handler.