Blinking Text Block style throwing errors - wpf

I'm trying to create a style in XAML that can be applied to any TextBlock element to make the text blink. Here is the style:
<Style x:Key="BlinkingTextBlock" TargetType="TextBlock">
<Style.Resources>
<Storyboard x:Key="FlashMe" RepeatBehavior="Forever">
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="0:0:0.5">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:1">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</Style.Resources>
<Style.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard x:Name="FlashMe" />
</EventTrigger>
</Style.Triggers>
</Style>
When I apply it to a text block
<TextBlock FontSize="16" FontStyle="Italic" FontWeight="Bold" Foreground="Red" Style="{StaticResource BlinkingTextBlock}" >
I get an error:
Must have a Storyboard object reference before this trigger action can execute.
Does anyone have an idea of where I need another storyboard?

The error says it all, you should bind to the "FlashMe" StoryBoard:
<BeginStoryboard Storyboard= "{StaticResource FlashMe}" />

Related

How to start Storyboard by means of data binding?

I have a Storyboard at Window resources as shown below.
<Window.Resources>
<!-- Storyboard as a window resource -->
<Storyboard
x:Key="NB"
x:Name="NB_resource"
Completed="NB_resource_Completed"
RepeatBehavior="5x">
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="NB_image"
Storyboard.TargetProperty="Source"
Duration="0:0:1.2">
<DiscreteObjectKeyFrame KeyTime="0:0:0">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="pack://application:,,,/CircleSurrogateButton;component/Images/NB_00.png" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:.3">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="pack://application:,,,/CircleSurrogateButton;component/Images/NB_01.png" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:.6">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="pack://application:,,,/CircleSurrogateButton;component/Images/NB_02.png" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:.9">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="pack://application:,,,/CircleSurrogateButton;component/Images/NB_03.png" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
The Storyboard can be started with the following string which is placed in regular Button.
<EventTrigger RoutedEvent="PreviewMouseLeftButtonDown">
<BeginStoryboard Storyboard="{DynamicResource NB}" />
</EventTrigger>
A question is How to use a data binding in order to start that Storyboard.
For example:
<DataTrigger Binding="{Binding Start_Storyboard}" Value="true">
<DataTrigger.EnterActions>
<BeginStoryboard Storyboard="{DynamicResource NB}"/>
</DataTrigger.EnterActions>
</DataTrigger>

WPF Animation not working correctly

I have the following storyboard for my Image control, however, when running this code, the last image does not get displayed:
<Image Height="15" Width="137" RenderTransformOrigin="0.415,4.583" Canvas.Left="104" Canvas.Top="13">
<Image.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding State, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Value="Reconnect">
<DataTrigger.EnterActions>
<BeginStoryboard Name="reconnectStoryBoardImageChange" >
<Storyboard>
<ObjectAnimationUsingKeyFrames
BeginTime="00:00:00" RepeatBehavior="Forever"
Storyboard.TargetProperty="(Image.Source)">
<DiscreteObjectKeyFrame KeyTime="00:00:01">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="Images/State/Reconnect.png" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="00:00:02">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="Images/State/Reconnect_2.png" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="00:00:03">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="Images/State/Reconnect_3.png" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="00:00:04">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="Images/State/Reconnect_4.png" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="reconnectStoryBoardImageChange"/>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
What this XAML does it to display different images at different times, but never displays reconnect_4 , it goes till _3 then back to the first image.
Am I doing something wrong?
You can find the explanation why it is not working the way you expect it here.
If the animation's Duration is Automatic or its Duration is equal to
the time of the last key frame, the animation ends. Otherwise, if the
animation's Duration is greater than the key time of the last key
frame, the animation holds the key frame value until it reaches the
end of its Duration.
So you should specify the Duration of the Storyboard. I'd do it like this:
<Style.Triggers>
<DataTrigger Binding="{Binding State, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Value="Reconnect">
<DataTrigger.EnterActions>
<BeginStoryboard Name="reconnectStoryBoardImageChange" >
<Storyboard>
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:04" RepeatBehavior="Forever" Storyboard.TargetProperty="(Image.Source)">
<DiscreteObjectKeyFrame KeyTime="00:00:00">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="Images/State/Reconnect.png" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="00:00:01">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="Images/State/Reconnect_2.png" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="00:00:02">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="Images/State/Reconnect_3.png" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="00:00:03">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="Images/State/Reconnect_4.png" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="reconnectStoryBoardImageChange"/>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
I specified 4 seconds as the Duration. The first image is shown from 00:00:00 to 00:00:01. The second image is shown from 00:00:01 to 00:00:02. The third image is shown from 00:00:02 to 00:00:03. Fourth image is shown from 00:00:03 to 00:00:04. Then it restarts.
In your case the last key frame lasts 0 seconds, because your storyboard ends too early.

Exception this freezable cannot be freezed while using DiscreteObjectKeyFrame

I have here some buttons that are inside a stackpanelin a wpf, the buttons have slightly curved corners. I want that there will be an animation that will turn the buttons into a circle if the mouse hovers over them. However this code here throws "System.InvalidOperationException, This Freezable cannot be frozen."
<StackPanel.Triggers>
<EventTrigger RoutedEvent="Button.MouseEnter">
<BeginStoryboard>
<Storyboard Name="CurveStoryboard" Storyboard.TargetProperty ="Button" >
<ObjectAnimationUsingKeyFrames>
<DiscreteObjectKeyFrame KeyTime="0:0:5">
<DiscreteObjectKeyFrame.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border CornerRadius="30,30,30,30" ></Border>
</ControlTemplate>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</StackPanel.Triggers>
Thanks a bunch.

wpf ObjectAnimationUsingKeyFrames setting the left value

In WPF, I'm trying to move an image from left to center, pause for a second, then move the image to the right.
I'm trying to achieve it using ObjectAnimationUsingKeyFrames.
<BeginStoryboard>
<Storyboard Storyboard.TargetName="RoundNumberText" >
<ObjectAnimationUsingKeyFrames Duration="0:0:1" Storyboard.TargetProperty="Left">
<DiscreteObjectKeyFrame Value="400" KeyTime="0:0:0.5"/>
<DiscreteObjectKeyFrame Value="1400" KeyTime="0:0:1.5"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
Somehow i got the error message on the TargetProperty that the object does not supported by this properties. I've tried with margin as well, but still giving error.
Appreciate if anyone could help.
To set the value for alignment, you need to do something like this:
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="MyImage"
Storyboard.TargetProperty="HorizontalAlignment">
<DiscreteObjectKeyFrame KeyTime="0:0:0">
<DiscreteObjectKeyFrame.Value>
<HorizontalAlignment>Center</HorizontalAlignment>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
Below is my example, where the image appears in the role of the Label:
<Grid>
<Grid.Triggers>
<EventTrigger SourceName="MoveToCenter" RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Test"
Storyboard.TargetProperty="HorizontalAlignment">
<DiscreteObjectKeyFrame KeyTime="0:0:0">
<DiscreteObjectKeyFrame.Value>
<HorizontalAlignment>Center</HorizontalAlignment>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames BeginTime="0:0:1"
Storyboard.TargetName="Test"
Storyboard.TargetProperty="HorizontalAlignment">
<DiscreteObjectKeyFrame KeyTime="0:0:0">
<DiscreteObjectKeyFrame.Value>
<HorizontalAlignment>Right</HorizontalAlignment>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
<Label x:Name="Test" Content="Test" Width="300" Height="200" Background="Aqua" HorizontalAlignment="Left" />
<Button Name="MoveToCenter" Content="MoveToCenter" Width="120" Height="30" HorizontalAlignment="Right" VerticalAlignment="Bottom" />
</Grid>

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