WPF stackpanel visibility animation - wpf

I have a stackpanel with a button which, when clicked, makes the stackpanel disappear. I want to animate the transition form visible to hidden, but haven't been able to.
I looked around for a while and bumped into something that looks like this:
<StackPanel Margin="80,60,60,80" Background="Gray">
<StackPanel.Triggers >
<EventTrigger >
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard TargetProperty="Visibility">
<DoubleAnimation Duration="0:0:5:0" From="Visible" To="Hidden"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</StackPanel.Triggers>
<Button Name="buttonTop" Content="TOP" Margin="40,40,40,40" Click="buttonTop_Click" Width="131" />
</StackPanel>
which of course, is not 100% there yet. Any ideas?

You can use
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ItemsHost"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
This is pretty much a setter in a storyboard, where KeyTime describes the time when the value should be set.
So the full storyboard would be like this:
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
To="0" Duration="0:0:5.0"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:5.0" Value="{x:Static Visibility.Hidden}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
edit: How to make the storyboard trigger when button is clicked:
<Button Content="Button" HorizontalAlignment="Left" Margin="337,221,0,0" VerticalAlignment="Top" Width="75">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
To="0" Duration="0:0:5.0"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:5.0" Value="{x:Static Visibility.Hidden}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>

Visibiltiy is a discrete value - it's either on or off, so animating will still result in a sudden disappearance rather than a gradual fading out. You could instead animate the Opacity of the StackPanel from 1 to 0, and then animate the Visibilty to Hidden (or Collapsed) after that.

Related

RoutedEvent TextBox.LostFocus not working in my WPF application

I am working with the WPF animations using Storyboards. What I want is to fade out all the content of the page as soon as my textbox gets focus, and to fade in everything back as soon as the focus is removed from the textbox. To do that, I have the following XAML with no code behind.
<Page.Triggers>
<EventTrigger RoutedEvent="TextBox.GotFocus">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="Grid1"
Storyboard.TargetProperty="Opacity"
From="1" To="0.1" Duration="0:0:0.2"
AutoReverse="False" >
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="TextBox.LostFocus">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="Grid1"
Storyboard.TargetProperty="Opacity"
From="0.1" To="1" Duration="0:0:0.2"
AutoReverse="False">
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
To move focus out of textbox, I have the following button:
<Button
Name="SearchButton"
Height="30" Width="30"
Grid.Column="1"
Focusable="True"
IsHitTestVisible="True"
Style="{StaticResource SearchButton}"
Padding="3,3,3,3"
Margin="3,3,3,3" Click="Button_Click"/>
When I run the app, clicking on the textbox makes the fade out work fine. But when I click on the button, the fade in does not kick in.
Can anyone please give me some insights?
You should place your triggers in the TextBox directly, not on the Page level:
<TextBox>
<TextBox.Triggers>
<EventTrigger RoutedEvent="TextBox.GotFocus">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="Grid1"
Storyboard.TargetProperty="Opacity"
From="1" To="0.1" Duration="0:0:0.2"
FillBehavior="HoldEnd">
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="TextBox.LostFocus">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="Grid1"
Storyboard.TargetProperty="Opacity"
From="0.1" To="1" Duration="0:0:0.2"
FillBehavior="Stop">
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBox.Triggers>
</TextBox>
Otherwise, the storyboards will be triggered for each and every GotFocus and LostFocus routed event of each UIElement on the Page because of these events' bubbling strategy.

How to play translate transform in xaml?

I have a button that I want to translate horizontally, so I use the storyboard like this:
<Button>
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="Studio" Storyboard.TargetProperty="RenderTransform.(TranslateTransform.X)" From="0" To="5000" Duration="0:0:2">
<DoubleAnimation.EasingFunction>
<CubicEase EasingMode="EaseInOut"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
but nothing happens
Nothing happens because there is no TranslateTransform in the Button's RenderTransform.
Just add one, and remove the Storyboard.TargetName from the DoubleAnimation :
<Button ...>
<Button.RenderTransform>
<TranslateTransform/>
</Button.RenderTransform>
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="RenderTransform.X"
To="5000" Duration="0:0:2">
<DoubleAnimation.EasingFunction>
<CubicEase EasingMode="EaseInOut"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>

Make WPF control disappear when lost focus

I have a StackPanel that is being used as a container for other menuing controls. I want the StackPanel to disappear when somewhere else on the UI is clicked (similar to typical menus/context menus). I'm struggling with how to do this. Any suggestions? I've tried event triggers in the style like below but it doesn't seem to work correctly.
<StackPanel.Style>
<Style TargetType="{x:Type StackPanel}">
<Style.Triggers>
<EventTrigger RoutedEvent="LostMouseCapture" >
<BeginStoryboard>
<Storyboard>
<DoubleAnimation From="1" To="0" Duration="0:0:0.1"
Storyboard.TargetProperty="Opacity"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
Set the stackPanel's trigger like this:
<EventTrigger RoutedEvent="MouseEnter" >
<BeginStoryboard>
<Storyboard>
<DoubleAnimation To="1" Duration="0:0:0.1"
Storyboard.TargetProperty="Opacity"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
and add this tag to Window (as well as other controls you want to when clicked, hide the stack panel):
<Window.Triggers>
<EventTrigger RoutedEvent="MouseDown">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation To="0" Duration="0:0:0.1"
Storyboard.TargetName="disappearingStackPanel"
Storyboard.TargetProperty="Opacity"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Window.Triggers>
You can also set IsHitTestVisible=False on controls that don't have mouse interaction so you don't have to add the trigger to them.

Setting the Visibility of an Element to Collapsed when Storyboard completes using XAML

I have a storyboard animation that fades a control out of view using the Opacity property. When it completes, I want to set the Visibility of the control to Collapsed.
I'd like to be able to do the reverse as well... Set the Visibility to Visible and then use a storyboard to fade the control into view.
I know I can hook up events, but I would like to do this all in XAML. Is it possible?
you can do this in the animation as well
<Window.Resources>
<Storyboard x:Key="OnLoaded1">
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="button" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static Visibility.Visible}"/>
<DiscreteObjectKeyFrame KeyTime="00:00:00.8000000" Value="{x:Static Visibility.Collapsed}"/>
<DiscreteObjectKeyFrame KeyTime="00:00:01.4000000" Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Storyboard="{StaticResource OnLoaded1}"/>
</EventTrigger>
</Window.Triggers>

WPF TextBlock text changed notify

I have a screen contain about 15-20 TextBlocks each one bind to a different property, at first all the TextBlocks are empty the text update come from other client.
The thing I want to do is to animate flashing text for 3 seconds when ever text change.
I used the below storyboard to make that happen:
<Setter Property="Visibility" Value="Visible"/>
<Style.Triggers>
<EventTrigger RoutedEvent="UIElement.MouseEnter">
<BeginStoryboard >
<Storyboard Duration="0:0:03">
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static Visibility.Visible}"/>
<DiscreteObjectKeyFrame KeyTime="00:00:00.5" Value="{x:Static Visibility.Hidden}"/>
<DiscreteObjectKeyFrame KeyTime="00:00:01" Value="{x:Static Visibility.Visible}"/>
<DiscreteObjectKeyFrame KeyTime="00:00:01.5" Value="{x:Static Visibility.Hidden}"/>
<DiscreteObjectKeyFrame KeyTime="00:00:02" Value="{x:Static Visibility.Visible}"/>
<DiscreteObjectKeyFrame KeyTime="00:00:02.5" Value="{x:Static Visibility.Hidden}"/>
<DiscreteObjectKeyFrame KeyTime="00:00:03" Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
Using the mouse enter event the text flash is fine but using the Binding.TargetUpdated event didn't trigger anything.
Anyone know about event that raise when the TextBlock text is changed ?
did you set the NotifyOnTargetUpdated property to true
<TextBlock Text="{Binding Path=YourProperty, NotifyOnTargetUpdated=True}" TargetUpdated="OnTargetUpdated"/>
Already a bit old, but here the solution in pure xaml:
<TextBlock VerticalAlignment="Center"
Text="{Binding ErrorMsg, NotifyOnTargetUpdated=True}">
<TextBlock.Triggers>
<EventTrigger RoutedEvent="Binding.TargetUpdated">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation BeginTime="0:0:0"
Duration="0:0:1"
From="0.0"
Storyboard.TargetProperty="Opacity"
To="1.0" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>

Resources