I have 2 DataTrigger that animates the background color of a button (with reverse), this part works fine.
The problem is that when the 2 triggers are fired in overlapping times, the first trigger fired does not reverse the color, when the second trigger stops it reverses the color to whatever was the color when the previous animation stopped.
What should I do?
This is the example code:
<DataTrigger Binding="{Binding IsUp}" Value="True">
<DataTrigger.EnterActions>
<StopStoryboard BeginStoryboardName="isDownStoryBoard"/>
<BeginStoryboard Name="isUpStoryBoard">
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="Background.GradientStops[0].Color" To="#b4e391" Duration="0:0:1" AutoReverse="True" RepeatBehavior="2x" />
<ColorAnimation Storyboard.TargetProperty="Background.GradientStops[1].Color" To="#61c419" Duration="0:0:1" AutoReverse="True" RepeatBehavior="2x" />
<ColorAnimation Storyboard.TargetProperty="Background.GradientStops[2].Color" To="#b4e391" Duration="0:0:1" AutoReverse="True" RepeatBehavior="2x" />
<ColorAnimation Storyboard.TargetProperty="Background.GradientStops[3].Color" To="#b4e391" Duration="0:0:1" AutoReverse="True" RepeatBehavior="2x" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
<DataTrigger Binding="{Binding IsDown}" Value="True">
<DataTrigger.EnterActions>
<StopStoryboard BeginStoryboardName="isUpStoryBoard"/>
<BeginStoryboard Name="isDownStoryBoard">
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="Background.GradientStops[0].Color" To="#efc5ca" Duration="0:0:1" AutoReverse="True" RepeatBehavior="2x" />
<ColorAnimation Storyboard.TargetProperty="Background.GradientStops[1].Color" To="#d24b5a" Duration="0:0:1" AutoReverse="True" RepeatBehavior="2x" />
<ColorAnimation Storyboard.TargetProperty="Background.GradientStops[2].Color" To="#ba2737" Duration="0:0:1" AutoReverse="True" RepeatBehavior="2x" />
<ColorAnimation Storyboard.TargetProperty="Background.GradientStops[3].Color" To="#f18e99" Duration="0:0:1" AutoReverse="True" RepeatBehavior="2x" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
There is a StopStoryboard Class that you can use to stop a running Storyboard with, but there is no ReverseStoryboard class. However, you can just create another Storyboard that runs in reverse to your original one that you start when you stop the original one. You can use the StopStoryboard class like this (from the linked page on MSDN):
<!-- Begin the Storyboard -->
<EventTrigger RoutedEvent="Button.Click" SourceName="BeginButton">
<BeginStoryboard Name="MyBeginStoryboard">
<Storyboard >
<DoubleAnimation
Storyboard.TargetName="myRectangle"
Storyboard.TargetProperty="Width"
Duration="0:0:5" From="100" To="500" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
...
<!-- Stop the Storyboard -->
<EventTrigger RoutedEvent="Button.Click" SourceName="StopButton">
<StopStoryboard BeginStoryboardName="MyBeginStoryboard" />
</EventTrigger>
Also, please see the Timeline.FillBehavior Property that you can set on the Storyboard which Gets or sets a value that specifies how the Timeline behaves after it reaches the end of its active period. You can set it to the FillBehavior.HoldEnd enumeration to get the Storyboard to keep it's last value when it ends.
Related
I have a button that has two triggers.
One is on IsMouseOver and the other one on mouseClick.
If I comment the IsMouseOver one out the other one works perfectly fine but if I use both then the mouseClick one is ignored.
This are my Triggers:
<ControlTemplate.Triggers>
<Trigger Property="local:MouseDownHelper.IsMouseLeftButtonDown"
Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="00:00:00.100"
Storyboard.TargetName="SendReportsButtonMainGrid"
Storyboard.TargetProperty="Background.Color"
To="{StaticResource ClickGray}" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="00:00:00.100"
Storyboard.TargetName="SendReportsButtonMainGrid"
Storyboard.TargetProperty="Background.Color"
To="{StaticResource HoverGray}" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsMouseOver"
Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="00:00:00.400"
Storyboard.TargetName="SendReportsButtonMainGrid"
Storyboard.TargetProperty="Background.Color"
To="{StaticResource HoverGray}" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="00:00:00.800"
Storyboard.TargetName="SendReportsButtonMainGrid"
Storyboard.TargetProperty="Background.Color"
To="{StaticResource HeaderGray}" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
The MouseDownHelper is from there as said it works wihout the other trigger.
How can I have the OnHover effect and another one if the button is clicked?
EDIT:
You can also use IsPressed that doesn't work either.
I have found a solution using StopStoryboard.
I also added a second animation when clicking and I'm using onEnter and onLeave instead of onHover.
<ControlTemplate.Triggers>
<Trigger Property="local:MouseDownHelper.IsMouseLeftButtonDown"
Value="True">
<Trigger.EnterActions>
<StopStoryboard BeginStoryboardName="StoryboardEnter"/>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="00:00:00.000"
Storyboard.TargetName="SendReportsButtonMainGrid"
Storyboard.TargetProperty="Background.Color"
To="{StaticResource HoverGray}" />
<ColorAnimation Duration="00:00:00.100"
Storyboard.TargetName="SendReportsButtonMainGrid"
Storyboard.TargetProperty="Background.Color"
To="{StaticResource ClickGray}" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="00:00:00.100"
Storyboard.TargetName="SendReportsButtonMainGrid"
Storyboard.TargetProperty="Background.Color"
To="{StaticResource HoverGray}" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard Name="StoryboardEnter">
<Storyboard>
<ColorAnimation Duration="00:00:00.200"
Storyboard.TargetName="SendReportsButtonMainGrid"
Storyboard.TargetProperty="Background.Color"
To="{StaticResource HoverGray}" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="00:00:00.400"
Storyboard.TargetName="SendReportsButtonMainGrid"
Storyboard.TargetProperty="Background.Color"
To="{StaticResource HeaderGray}" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
I'm developing a WPF application with C# and .NET Framework 4.7.
I have this animation:
<Style.Triggers>
<EventTrigger RoutedEvent="ContentChanged">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="0:0:0.1" Storyboard.TargetProperty="(Label.Background).(SolidColorBrush.Color)"
To="Yellow" AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
I'm trying to change the background colour to yellow, and then come back to white again, but I think AutoReverse doesn't mean that.
I have also tried:
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Label.Background).(SolidColorBrush.Color)"
To="Yellow" FillBehavior="Stop" BeginTime="0:0:0" Duration="0:0:0.3"/>
<ColorAnimation Storyboard.TargetProperty="(Label.Background).(SolidColorBrush.Color)"
From="Yellow" To="White"
BeginTime="0:0:0.3" Duration="0:0:1"/>
</Storyboard>
</BeginStoryboard>
But, at the end, the background colour is yellow.
The effect I'm trying to achieve is to change background colour when Label's content changes, and then come back quickly to its original colour. I want to create a visual effect to notice which label has changed its content.
How can I change the colour to yellow and then change it to white again?
Add another ColorAnimation to the Storyboard and set its BeginTime property to a value greater than or equal to the Duration of the first one, e.g.:
<EventTrigger RoutedEvent="ContentChanged">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation BeginTime="0:0:0" Duration="0:0:1"
Storyboard.TargetProperty="(Label.Background).(SolidColorBrush.Color)"
To="Yellow"/>
<ColorAnimation BeginTime="0:0:1" Duration="0:0:1"
Storyboard.TargetProperty="(Label.Background).(SolidColorBrush.Color)"
To="White"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
I have a DataGrid which contains a list of item that implement a boolean property called ResultChanged, this property allow me to create a blink effect on a particular cell of the DataGrid, in particular, if the property is setted to true then the cell of the DataGrid will colored by orange and blinking for 5 seconds, at the end of the animation, the color will keeped on the DataGrid and this working well for me, except for one problem.
Problem
When I click on the DataGrid (any rows) the color applied by the animation will be removed, but I want that such color remain on the cell.
This is my code:
<DataGridTextColumn Header="{DynamicResource hour}" Binding="{Binding Result}">
<DataGridTextColumn.CellStyle>
<Style TargetType="{x:Type DataGridCell}" BasedOn="{StaticResource MaterialDesignDataGridCell}">
<Style.Triggers>
<DataTrigger Binding="{Binding ResultChanged}" Value="True" >
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<Storyboard x:Name="Blink"
AutoReverse="True"
RepeatBehavior="5x">
<ColorAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="00:00:01"
Value="Orange" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames
BeginTime="00:00:00"
Storyboard.TargetProperty="(Foreground).(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="00:00:01"
Value="Black" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard AutoReverse="False">
<ColorAnimationUsingKeyFrames BeginTime="00:00:10" Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="00:00:01" Value="Orange" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
someone know what I did wrong?
The animation's effects will be lost when you select or unselect the row affected by the animation, because DataGrid changes the foreground and background brushes of the selected row. Now, normally, the animation's changes to the Foreground and Background properties would have precedence over those changes for the selected row.
But your animation does not animate Foreground and Background! Instead, it animates Foreground.Color and Background.Color; these changes have no precedence and will be lost when something else changes Foreground or Background directly.
Therefore, your animation must animate Foreground and Background directly. Then, the changes will remain in effect even after the animation has ended.
You could achieve this, for example, by using the BrushAnimation class from the answer in question Brush to Brush Animation and using a storyboard similar to this:
<DataTrigger Binding="{Binding ResultChanged}" Value="True" >
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<Storyboard x:Name="Blink"
RepeatBehavior="5x">
<local:BrushAnimation Storyboard.TargetProperty="Background"
BeginTime="00:00:00" Duration="0:0:0.5" From="White" To="Orange" />
<local:BrushAnimation Storyboard.TargetProperty="Foreground"
BeginTime="00:00:00" Duration="0:0:0.5" From="Yellow" To="Black" />
</Storyboard>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
EDIT:
Here is a solution that allows AutoReverse to be set to true:
<DataTrigger Binding="{Binding ResultChanged}" Value="True" >
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<!-- The next two animations will take 10 seconds: -->
<Storyboard x:Name="Blink" AutoReverse="True" RepeatBehavior="5x">
<local:BrushAnimation Storyboard.TargetProperty="Background"
BeginTime="00:00:00" Duration="0:0:1" From="White" To="Orange"/>
<local:BrushAnimation Storyboard.TargetProperty="Foreground"
BeginTime="00:00:00" Duration="0:0:1" From="Yellow" To="Black"/>
</Storyboard>
<!-- Same animations as above, but BeginTime offset by 10 seconds and neither repeat nor auto reverse: -->
<Storyboard x:Name="finalBlink" BeginTime="00:00:10">
<local:BrushAnimation Storyboard.TargetProperty="Background"
BeginTime="00:00:00" Duration="0:0:1" From="White" To="Orange"/>
<local:BrushAnimation Storyboard.TargetProperty="Foreground"
BeginTime="00:00:00" Duration="0:0:1" From="Yellow" To="Black"/>
</Storyboard>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
I'm developing a WPF Application for Touch Devices. I want a behaviour like in Android Browser, if you focus a TextBox the screen 'zooms' in so you only see the TextBox and the virtual Keyboard.
I have already tried Scaling the TextBox and setting the Position if it has Focus but that doesn't work right. If somebody could point me in the right direction i would appreciate that.
you can achieve this function from this code
<TextBox Background="LightGreen" Width="100" Height="100" BorderBrush="Green">
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation Duration="0:0:0.400" To="3" Storyboard.TargetProperty="BorderThickness" />
<DoubleAnimation Duration="0:0:0.300" To="125" Storyboard.TargetProperty="Height" />
<DoubleAnimation Duration="0:0:0.300" To="125" Storyboard.TargetProperty="Width" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation Duration="0:0:0.250" To="0" Storyboard.TargetProperty="BorderThickness" />
<DoubleAnimation Duration="0:0:0.150" To="100" Storyboard.TargetProperty="Height" />
<DoubleAnimation Duration="0:0:0.150" To="100" Storyboard.TargetProperty="Width" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
I want to show all my windows except Main page from right to left transition style.
I tried this
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard>
<!--<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:2" FillBehavior="HoldEnd" />
</Storyboard>-->
<Storyboard >
<ThicknessAnimation Duration="0:0:.8" Storyboard.TargetProperty="Margin" To="-1200,0,-100,0" AccelerationRatio=".1"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Window.Triggers>
The same if i put stackpanel trigger it's coming from left to right inside the window.
Like wise i need for showing window itself.
How to achieve this ?
A DoubleAnimation on the Left property should do the trick
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard>
<Storyboard >
<DoubleAnimation Duration="0:0:.8" Storyboard.TargetProperty="Left" From="1920" To="0" AccelerationRatio=".1"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Window.Triggers>