Reputation: 1191
I have a window that's intended to fade in when shown. The first time it's used, the animation doesn't run. On subsequent uses, it works fine. It's a requestor that I instantiate to show something- I don't keep it around and re-use the instances. I instantiate the requestor, set various properties such as .Top and .Left and then call ShowDialog. In the constructor I'm setting the DataContext. If I comment that out (since another thread suggested this could be caused by setting the data context while the animation was playing) then it gets rid of the problem. Yet I'm not calling ShowDialog until way after the constructor will be called. And because I'm instantiating a new instance every time I want to use it, I don't understand why it's only on the first run that there's a problem.
It's as if an assembly is being loaded the first time, but the VS output window doesn't show this happening.
The window starts at zero opacity, so by becoming visible it shows the animation's being triggered, it's just not having time to run. If I set BeginTime to be half a second then it does work every time, but obviously it's more sluggish when it's appearing in response to a button press and may still not be adequate on slower machines.
I'm defining the animation in XAML with
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard>
<Storyboard Name="FormFade">
<DoubleAnimation Name="FormFadeAnimation"
Storyboard.TargetProperty="(Window.Opacity)"
From="0.0" To="1.0" Duration="0:0:0.25"
AutoReverse="False" RepeatBehavior="1x"
BeginTime="0:0:0"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Window.Triggers>
Is there a more appropriate event to trigger on? I tried Window.Initialized and Window.IsVisibleChanged but neither seem to be routed events so they throw an exception when the XAML is parsed.
I could shift it all to code behind (since fading out has to be done there anyway) but prefer stuff to be in the xaml if it can.
I could assign the DataContext from a Dispatcher.BeginInvoke, but that seems messy and where there's fields to be populated in the future it'd probably happen after the animation and look bad, so I'd just be hiding the problem till later.
Has anyone any thoughts on this?
Upvotes: 3
Views: 1569
Reputation: 1906
try this code:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="WpfApplication2.MainWindow"
x:Name="thisWindow"
Title="MainWindow"
Width="640" Height="480" AllowsTransparency="True" WindowStyle="None">
<Window.Resources>
<Storyboard x:Key="MyStoryboard">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="thisWindow">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.25" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Storyboard="{StaticResource MyStoryboard}"/>
</EventTrigger>
</Window.Triggers>
<Grid x:Name="LayoutRoot"/>
</Window>
Upvotes: 1