I want to change the background color to red instantly if a property is true. Then revert slowly back to default background color.
My first attempt, problem: Default color appears instantly and not reverting slowly over time
<DataTrigger Binding="{Binding HasValueChanged}" Value="True">
<Setter Property="Background" Value="Red" />
</DataTrigger>
<DataTrigger Binding="{Binding HasValueChanged}" Value="False">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="Background.(SolidColorBrush.Color)" Duration="0:0:5" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
My second attempt, problem: Color reverses like it should, but never goes red again if the property remains true
<DataTrigger Binding="{Binding HasValueChanged}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation To="Red" AutoReverse="True" Storyboard.TargetProperty="Background.(SolidColorBrush.Color)" Duration="0:0:5" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
As long as you don't set a Timeline's FillBehavior to Stop, it keeps holding the final property value until it is replaced by another Timeline.
So this works:
<DataTrigger Binding="{Binding HasValueChanged}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="Background.Color"
To="Red" Duration="0"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="Background.Color"
From="Red" Duration="0:0:1"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
Related
I would like to create simple animation which type is based on some value. I need to change color of text in TextBlock control, but the target color is depending on bounded variable. I've already created 2 DataTriggers and depending on a value of my bounded variable, a proper animation should start. At the beginning everything seems to work properly (AnimationValue is equal to 0 on start), when the value changes to 1, animation runs, then value returns to 0. The problem is, when the value turns to 2 (Animation with another color also runs) and then again 0, the first animation is not going to run anymore but the second one still works in a proper way.
<Border
Grid.Column="0"
Background="Transparent">
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="32"
Foreground="White"
Text="MyText">
<TextBlock.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=AnimationValue}" Value="1">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetProperty="Foreground.Color"
To="Gray"
Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetProperty="Foreground.Color"
To="White"
Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
<DataTrigger Binding="{Binding Path=AnimationValue}" Value="2">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetProperty="Foreground.Color"
To="Firebrick"
Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetProperty="Foreground.Color"
To="White"
Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</Border>
There is no problem with setting a correct value - i've checked it using a debugger and everytime correct value is set. 0 is always between 1 and 2. DataContext is also not a problem - a connection between View and ViewModel is not being broken. I've noticed that broken animation is always the first one in xaml file. Now the "Gray" animation stops working correctly, but if i change order in xaml file, firebrick animation will be the broken one. Thanks for any help.
It looks like running StoryBoards in triggers is a weird thing. I don't have a technical explanation as to how they behave but here is a SO question where I found an answer for you.
Here is some code based on the answer above that works:
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=AnimationValue}" Value="0">
<DataTrigger.EnterActions>
<StopStoryboard BeginStoryboardName="Animation1" />
<StopStoryboard BeginStoryboardName="Animation2" />
<BeginStoryboard x:Name="Animation0">
<Storyboard>
<ColorAnimation
Storyboard.TargetProperty="Foreground.Color"
To="White"
Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
<DataTrigger Binding="{Binding Path=AnimationValue}" Value="1">
<DataTrigger.EnterActions>
<StopStoryboard BeginStoryboardName="Animation0" />
<StopStoryboard BeginStoryboardName="Animation2" />
<BeginStoryboard x:Name="Animation1">
<Storyboard>
<ColorAnimation
Storyboard.TargetProperty="Foreground.Color"
To="Gray"
Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
<DataTrigger Binding="{Binding Path=AnimationValue}" Value="2">
<DataTrigger.EnterActions>
<StopStoryboard BeginStoryboardName="Animation0" />
<StopStoryboard BeginStoryboardName="Animation1" />
<BeginStoryboard x:Name="Animation2">
<Storyboard>
<ColorAnimation
Storyboard.TargetProperty="Foreground.Color"
To="Firebrick"
Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
I am attempting to animate the background colour of a label on the data change of a property. The label is changing colour up to the value of 3. however if the property returns to a value of 1, the animation stays on the previous colour. My XAML is below.
<Style x:Key="Colors" TargetType="Label">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Window},
Path=DataContext.ColorNo}" Value="1">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"
To="Red"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Window},
Path=DataContext.ColorNo}" Value="2">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"
To="Yellow"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Window},
Path=DataContext.ColorNo}" Value="3">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"
To="Green"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
Label XAML
<Label x:Name="vClock" Content="{Binding Path=Clock,Mode=OneWay}" FontSize="25" Style="{StaticResource Colors}">
</Label>
I think you need to remove the other active storyboard first, but it's is better to proceed declaring your storyboard in the resources:
<Storyboard x:key="Value 1">
<ColorAnimation
Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"
To="Red"/>
</Storyboard>
<Storyboard x:key="Value 2">
<ColorAnimation
Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"
To="Yellow"/>
</Storyboard>
<Storyboard x:key="Value 3">
<ColorAnimation
Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"
To="Green"/>
</Storyboard>
then look at the datatrigger
<Style x:Key="Colors" TargetType="Label">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Window},
Path=DataContext.ColorNo}" Value="1">
<DataTrigger.EnterActions>
<StopStoryboard BeginStoryboardName="Value2" />
<StopStoryboard BeginStoryboardName="Value3" />
<BeginStoryboard Storyboard="{StaticResource Value1}"
x:Name="Value1" />
</DataTrigger.EnterActions>
</DataTrigger>
...
</Style.Triggers>
</Style>
Do the same for all the triggers
I'm getting this exception , i'm trying to change the texenter code heretbox width when the mouse on over the textbox
this is thh exception :
Cannot animate the 'Width' property on a
'System.Windows.Controls.TextBox' using a
'System.Windows.Media.Animation.DoubleAnimation'. For details see the
inner exception.
<Style TargetType="TextBox">
<Setter Property="BorderBrush" Value="#248FB3" />
<Setter Property="TextWrapping" Value="Wrap"/>
<Setter Property="AcceptsReturn" Value="True"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.2" Storyboard.TargetProperty="Width" To="250" >
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.2" Storyboard.TargetProperty="Width"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsKeyboardFocusWithin" Value="true">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.2" Storyboard.TargetProperty="Width" To="250"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.2" Storyboard.TargetProperty="Width"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
You have to set either Width on your TextBox element or, From property on DoubleAnimation. When you don't set either, it gets default value of the Width property which is Double.NaN, so it doesn't know from where to start.
The default "Grid" is displayed.
In step one and "Hide_MouseUp", animation works.
And then in no way responds to IsEnabled.
Please Please help me to solve this problem.
I am waiting for your warm response :)
style:
<Style x:Key="ShowHideVisibilityStyle" TargetType="{x:Type Grid}">
<Setter Property="Opacity" Value="1"></Setter>
<Setter Property="Margin" Value="0,50,0,0"></Setter>
<Setter Property="IsEnabled" Value="True" />
<Style.Triggers>
<Trigger Property="IsEnabled" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="Opacity"
From="0" To="1" Duration="0:0:0.5" />
<ThicknessAnimation
Storyboard.TargetProperty="Margin"
From="-600,50,0,0"
To="0,50,0,0"
Duration="0:0:0.1"
/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="Opacity"
From="1" To="0" Duration="0:0:0.5" />
<ThicknessAnimation
Storyboard.TargetProperty="Margin"
BeginTime="0:0:0.5"
To="-600,50,0,0"
Duration="0:0:0" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
XAML:
<Grid x:Name="SettingPage" Width="290" Style="{DynamicResource ShowHideVisibilityStyle}">
<!-- code -->
</Grid>
Code Test For Change status IsEnabled to {False or True}
private void Hide_MouseUp(object sender, MouseButtonEventArgs e){
SettingPage.IsEnabled = false;
}
private void Show_MouseUp(object sender, MouseButtonEventArgs e){
SettingPage.IsEnabled = true;
}
Hi, I find the solution :)
for using two triggers on one property "Trigger.EnterActions" and "Trigger.ExitActions" should be used instead of using two separate Triggers
excuse me for my bad english :D
Code:
<Style.Triggers>
<Trigger Property="IsEnabled" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<!-- Animation -->
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<!-- Animation -->
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
It's a simple fix. Just move the "Enabling" Animation into an ExitTrigger:
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="Opacity"
From="1" To="0" Duration="0:0:0.5" />
<ThicknessAnimation
Storyboard.TargetProperty="Margin"
BeginTime="0:0:0.5"
To="-600,50,0,0"
Duration="0:0:0" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="Opacity"
From="0" To="1" Duration="0:0:0.5" />
<ThicknessAnimation
Storyboard.TargetProperty="Margin"
From="-600,50,0,0"
To="0,50,0,0"
Duration="0:0:0.1"
/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
I have a little question about my code:
<Style TargetType="{x:Type Grid}">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Status.IsObjectSaving}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
<Trigger Property="Visibility" Value="Visible">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty = "Opacity"
From ="1"
To = "0"
BeginTime = "0:0:0"
Duration = "0:0:2" />
<ObjectAnimationUsingKeyFrames
Storyboard.TargetProperty = "Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:2"
Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
When my object would be saved so the grid should be open an show some information. When I start the program for the first time it works, but the second time it doesn't work. So I hope you can help me.
Thanks Daniel
p.s. sorry for my horrible english!
Thanks for answering! I tried to set the values with the following code:
<DataTrigger Binding="{Binding Status.IsObjectSaving}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty = "Opacity"
From = "0"
To = "1"
BeginTime = "0:0:0"
Duration = "0:0:2" />
<ObjectAnimationUsingKeyFrames
Storyboard.TargetProperty = "Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:2"
Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty = "Opacity"
From = "1"
To = "0"
BeginTime = "0:0:2"
Duration = "0:0:2" />
<ObjectAnimationUsingKeyFrames
Storyboard.TargetProperty = "Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:2"
Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
But it's not working. So can you help me to modify the code in a right way?
thanks
Daniel
Animations change values with higher precedence, once the visibility is changed that way the trigger will not be able to modify it. You can replace the setter with an animation (enter and exit actions), that way they have the same precedence.