I want to create an animated control which can fade in and out, triggered by a bool value. For this purpose I made a custom control 'FadeHeaderControl':
public class FadeHeaderControl : ContentControl
{
public static readonly DependencyProperty IsAnimatedProperty = DependencyProperty.Register(
"IsAnimated", typeof (bool), typeof (FadeHeaderControl), new FrameworkPropertyMetadata(default(bool)));
public bool IsAnimated
{
get { return (bool) GetValue(IsAnimatedProperty); }
set { SetValue(IsAnimatedProperty, value); }
}
static FadeHeaderControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(FadeHeaderControl), new FrameworkPropertyMetadata(typeof(FadeHeaderControl)));
}
}
When the IsAnimated Dependency Property gets set to true (via Binding) the header should slide in (user notification that something has changed)
My MainWindow.xaml is here:
<Window.DataContext>
<wpfApplication1:MainWindowViewModel/>
</Window.DataContext>
<StackPanel>
<wpfApplication1:FadeHeaderControl x:Name="Myrect" VerticalAlignment="Top" IsAnimated="{Binding AnimationStarts}">
<Grid Background="Chartreuse" Width="Auto">
<Button Margin="10" HorizontalAlignment="Right">Button</Button>
</Grid>
</wpfApplication1:FadeHeaderControl>
<Button Margin ="50" Command="{Binding TriggerAnimationCommand}">Change visibility</Button>
</StackPanel>
and the viewmodel:
public class MainWindowViewModel : ViewModelBase
{
private bool _animationStarts;
public bool AnimationStarts
{
get { return _animationStarts; }
set
{
_animationStarts = value;
RaisePropertyChanged(() => AnimationStarts);
}
}
public ICommand TriggerAnimationCommand
{
get { return new RelayCommand(TriggerAnimation); }
}
private void TriggerAnimation()
{
AnimationStarts = !AnimationStarts;
}
}
the problem comes now in the Style for FadeHeaderControl:
<ResourceDictionary>
<Storyboard x:Key="HeaderFadeInAnimation">
<DoubleAnimation
Storyboard.TargetProperty="Height"
From="0"
To="{Binding RelativeSource={RelativeSource AncestorType={x:Type wpfApplication1:FadeHeaderControl}}, Path=ActualHeight}"
Duration="0:0:0.5"
BeginTime="0:0:0"
/>
</Storyboard>
<Storyboard x:Key="HeaderFadeOutAnimation">
<DoubleAnimation
Storyboard.TargetProperty="Height"
From="{Binding RelativeSource={RelativeSource AncestorType={x:Type wpfApplication1:FadeHeaderControl}}, Path=ActualHeight}"
To="0"
Duration="0:0:0.5"
BeginTime="0:0:0"
/>
</Storyboard>
<Style TargetType="{x:Type wpfApplication1:FadeHeaderControl}" x:Shared="False">
<Setter Property="IsAnimated" Value="False"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type wpfApplication1:FadeHeaderControl}">
<ContentPresenter x:Name="ContentPresenter" ContentSource="Content"></ContentPresenter>
<ControlTemplate.Triggers>
<Trigger Property="IsAnimated" Value="True">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource HeaderFadeInAnimation}"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource HeaderFadeOutAnimation}"/>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
How can I bind the 'To' or 'From' values of the double animation to the actual height of the FadeHeaderControl inside this style - or is this not possible because of the storyboard architecture. If I set the values to static numbers everything works like expected.
Should I replace the Trigger with an EventTrigger and create a RoutedEvent in my FadeHeaderControl?
Regards, and thanks for your help.