I would like to animate multiple controls after each other if a property changes in the DataContext
. For example, if a list is empty, then display a message, however if there is a new item added to the list, display the ListBox
instead. This can be done easily, but visibility change should be animated.
Checked every solution google offered, but those are using EventTriggers
bound to e.g. MouseMove
which are not suitable in this case.
The following error message comes: "TargetName property cannot be set on a Style Setter."
Sometimes I get the following exception: "A storyboard tree in a style cannot specify a TargetName. remove TargetName (0)"
I created a sample project to easily demonstrate the problem and the solution I tried which does not work. By pressing the button, the first label should fade out and the other one should fade in and by pressing again it happens vice versa.
XAML:
<Window x:Class="WpfApp1.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:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="100" Width="200">
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label x:Name="label1" Content="Hide me" HorizontalAlignment="Center"/>
<Label x:Name="label2" Content="This is the real content" HorizontalAlignment="Center">
<Label.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding ShowRealContent}" Value="False">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="label1" Storyboard.TargetProperty="Opacity" From="1.0" To="0.0" Duration="0:0:0.5"/>
<DoubleAnimation Storyboard.TargetName="label2" Storyboard.TargetProperty="Opacity" From="0.0" To="1.0" Duration="0:0:0.5"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
<DataTrigger Binding="{Binding ShowRealContent}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="label1" Storyboard.TargetProperty="Opacity" From="0.0" To="1.0" Duration="0:0:0.5"/>
<DoubleAnimation Storyboard.TargetName="label2" Storyboard.TargetProperty="Opacity" From="1.0" To="0.0" Duration="0:0:0.5"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Label.Style>
</Label>
<Button Grid.Row="1" Click="Button_Click" Content="Click me to swap labels" Width="Auto" HorizontalAlignment="Center"/>
</Grid>
Code behind:
public partial class MainWindow : Window, INotifyPropertyChanged
{
private bool m_ShowRealContent = false;
public event PropertyChangedEventHandler PropertyChanged;
public bool ShowRealContent
{
get { return m_ShowRealContent; }
set { m_ShowRealContent = value; OnPropertyChanged(); }
}
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
ShowRealContent = !ShowRealContent;
}
private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}