I'm trying to animate the background colour on a grid to change, once an event happens, but I can't get it working, I can get it to change colour immediately (via data triggers), but as soon as I try to introduce an animation into it, then I can't get it working (the animation doesn't seem to come into effect).
This is the current XAML I'm using (though I've tried various variations and cannot get it to animate):
<DataTrigger Binding="{Binding ElementName=me, Path=Viewed}" Value="False">
<Setter Property="Background" Value="LightYellow" />
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="00:00:02" To="White" Storyboard.TargetProperty="(Grid.Background).(SolidColorBrush.Color)"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
<!--
<DataTrigger Binding="{Binding ElementName=me, Path=Viewed}" Value="True">
<Setter Property="Background" Value="White" />
</DataTrigger>
-->
Where Viewed is a dependency property (bool) on my Control. Any hints in the right direction would be appreciated. I've also tried setting it as an EventTrigger on a raised event which happens when the bool switches to true.
Thanks to Clemens helps, figured out what I needed to do:
<SolidColorBrush x:Key="GridColourBrush" Color="LightYellow" />
<Style x:Key="GridStyle" TargetType="Grid">
<Setter Property="Background" Value="White" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=me, Path=Viewed}" Value="False">
<Setter Property="Background" Value="{StaticResource GridColourBrush}" />
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="00:00:02" To="White" Storyboard.TargetProperty="(Grid.Background).(SolidColorBrush.Color)"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
<!-- snipped stuff -->
<Grid MinWidth="525" x:Name="ContainerGrid" Style="{StaticResource GridStyle}" Background="{StaticResource GridColourBrush}" />
So setting the background to be flat white by default, then if the DP bool is false, change the background to the static solid colour brush, which I can then animate via the exit actions.
What i meant was simply that instead of
<Grid Background="LightYellow">
</Grid>
you would have to write
<Grid>
<Grid.Background>
<SolidColorBrush Color="LightYellow" />
</Grid.Background>
</Grid>
No need to have an extra resource.
Related
I have a button which shows a text and an image:
For this I use a StackPanel with a TextBlock and an Image inside of it.
When the variable "ActiveState" changes the Background of the StackPanel should change too, for this I use DataTriggers
ActiveState=0 -> Red /
ActiveState=1 -> Blue /
ActiveState=2 -> blinking Blue (for this I use a Storyboard and a Color Animation)
The blinking Trigger (Value=2) is working fine, but the two other Triggers (Value=0 + Value=1) are not working.
When I remove the Background of the Stackpanel (Background="Transparent") the first two Triggers are working but the last one get the following Exception:
An unhandled exception of type 'System.InvalidOperationException' occurred in PresentationFramework.dll
Additional information: Background property does not point to a dependencyobject in path '(0).(1)'
This is my code:
<Button>
<Button.Template>
<ControlTemplate TargetType="Button">
<StackPanel Orientation="Horizontal" Name="SelectButtonStackpanel" Background="Transparent">
<TextBlock Text="{Binding Text}"/>
<Image Source="{Binding Image}" Stretch="Uniform" Height="40" Width="40"/>
<StackPanel.Style>
<Style TargetType="{x:Type StackPanel}">
<Style.Triggers>
<DataTrigger Binding="{Binding ActiveState}" Value="0">
<Setter Property="Background" Value="Red"/>
</DataTrigger>
<DataTrigger Binding="{Binding ActiveState}" Value="1">
<Setter Property="Background" Value="Blue"/>
</DataTrigger>
<DataTrigger Binding="{Binding ActiveState}" Value="2">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetProperty="(StackPanel.Background).(SolidColorBrush.Color)"
To="Blue" Duration="0:0:1" AutoReverse="True" RepeatBehavior="Forever"
>
</ColorAnimation>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetProperty="(StackPanel.Background).(SolidColorBrush.Color)"
Duration="0:0:1"
>
</ColorAnimation>
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
</StackPanel>
</ControlTemplate>
</Button.Template>
</Button>
Do you have any idea how I get all three Triggers working?
best regards
Phil
When you directly set Background="Transparent" on the StackPanel, this has higher precedence than a value set from a Style Setter. So remove the direct assignment and add another Setter for the default Background.
Besides that, if you want to animate Background.Color you should always explictly assign SolidColorBrushes instead of predefined Brushes like Background="Red".
<StackPanel Orientation="Horizontal" Name="SelectButtonStackpanel">
<StackPanel.Style>
<Style TargetType="StackPanel">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="Transparent"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding ActiveState}" Value="0">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="Red"/>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding ActiveState}" Value="1">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="Blue"/>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding ActiveState}" Value="2">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetProperty="Background.Color"
To="Blue" Duration="0:0:1"
AutoReverse="True" RepeatBehavior="Forever">
</ColorAnimation>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
</StackPanel>
I've tried to recreate a material design kind of button. One of the animations of this button is that upon mouse over is that the color of the button changes to a darker hue of the original color.
In order to realise this for every color, I overlay my button with a rectangle and change it's opacity between 25 % and 0 % depending on mouse over or not. This style is implemented in the style of the rectangle. But it appears that this style is only executed before I click. Once I click the button, this style trigger is not executed anymore.
I've also implemented a animation to change the opacity of the rectangle to 40 % when the button is clicked. this animation however, is still visible after the first click.
I thought that it might be because the rectangle's style is included in the control template. But I don't know how to extract those styles from the control template to the button's style.
<Style x:Key="MaterialFlatButton" TargetType="Button">
<Setter Property="Foreground" Value="Black"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Rectangle RadiusX="4" RadiusY="4" Fill="#000000" Panel.ZIndex="1" x:Name="Reccie">
<Rectangle.Style>
<Style TargetType="{x:Type Rectangle}">
<Setter Property="Opacity" Value="0"/>
<!--These styles-->
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value="0.26"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="false">
<Setter Property="Opacity" Value="0"/>
</Trigger>
<EventTrigger RoutedEvent="MouseLeftButtonDown">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="0.4" Duration="0:0:0.25"/>
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:0.25" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"
Margin="16 0 16 0" TextBlock.FontFamily="{StaticResource LatoMedium}"
TextBlock.FontSize="{StaticResource FontSizeBody}" Typography.Capitals="AllSmallCaps"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<!--Should go here perhaps?-->
<Style.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#000000"/>
<Setter Property="Opacity" Value="0.26"/>
</Trigger>
</Style.Triggers>
</Style>
edit: does it do what you want if you set FillBehavior="Stop"?
<EventTrigger RoutedEvent="MouseLeftButtonDown">
<BeginStoryboard>
<Storyboard FillBehavior="Stop">
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="0.26" To="0.4" Duration="0:0:0.25"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
I want to change the grid background via binding, if a condition is true.
I am using the MVVM light framework.
<Grid.Style>
<Style TargetType="Grid">
<Style.Triggers>
<DataTrigger Binding="{Binding SuccessBooked, UpdateSourceTrigger=PropertyChanged}"
Value="True">
<!--Setter Property="Background" Value="LimeGreen" />-->
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation To="LimeGreen"
Storyboard.TargetName="ActualWeightBg"
Storyboard.TargetProperty="Background"
FillBehavior="Stop"
Duration="0:0:12"/>
<!--<DoubleAnimation Storyboard.TargetProperty="Opacity"
From="0.0" To="1.0" Duration="0:0:15"/>-->
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
<DataTrigger Binding="{Binding LowerBooked, UpdateSourceTrigger=PropertyChanged}"
Value="True">
<Setter Property="Background" Value="Red" />
</DataTrigger>
<DataTrigger Binding="{Binding HigherBooked, UpdateSourceTrigger=PropertyChanged}"
Value="True">
<Setter Property="Background" Value="DarkOrange" />
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
The compiler complains:
If I remove Storyboard.TargetName="ActualWeightBg":
<ColorAnimation To="LimeGreen"
Storyboard.TargetProperty="Background"
FillBehavior="Stop"
Duration="0:0:12"/>
I get this exception:
Exception thrown: 'System.InvalidOperationException' in PresentationFramework.dll
I want that background color is going to change for 5s, after that it should change back to the standard color.
Update
So when a background color is not set, it will throw the error:
Cannot resolve all property references in the property path
'Background.Color'. Verify that applicable objects support the
properties.
As you see here, the background color is not set
then the error will occur:
But when the background is set:
Then it will work as expected.
How can I set an animated background color, without background color being set.
It is an usercontrol.
First of all, StyleTriggers in general dont support TargetNames.
AFAIK only TemplateTriggers do support them.
Your DataTrigger should look like this.
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="Background.Color" To="LimeGreen"
FillBehavior="Stop" AutoReverse="True" Duration="0:0:5" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
Notice the Storyboard.TargetProperty="Background.Color". Also your TimeSpan was too high. Another thing is setting the AutoReverse to true.
EDIT
To get this Trigger to work, in the Grid's Style there has an initial Background to be set.
<Style TargetType="Grid">
<Setter Property="Background" Value="Red"/>
I've just started with WPF (I'm sorry if the question is too obvious), and I managed to put together this mouseover style. The background color animates to a darker color. I now want to also animate the text to white, so it's easier to read.
This is how I tried to add it, but it gives me the error "Cannot resolve all property references in the property path 'TextBlock.Foreground'. Verify that applicable objects support the properties" when I mouseover it.
<Border Background="#e6ebf3" CornerRadius="0,10,0,10" >
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="#e6ebf3" />
<Setter Property="TextBlock.Foreground" Value="Black"/>
<Style.Triggers>
<EventTrigger RoutedEvent="UIElement.MouseEnter">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="0:0:0.1" Storyboard.TargetProperty="Background.Color" To="#6d809b" />
<ColorAnimation Duration="0:0:0.1" Storyboard.TargetProperty="TextBlock.Foreground" To="white" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="UIElement.MouseLeave">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="0:0:0.1" Storyboard.TargetProperty="Background.Color" To="#e6ebf3" />
<ColorAnimation Duration="0:0:0.1" Storyboard.TargetProperty="TextBlock.Foreground" To="Black" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</Border.Style>........
I found an alternative way without using storyboard or animations, so I'll post it just in case. Still wondering about the original one, though.
<Border CornerRadius="0,10,0,10" >
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="#e6ebf3" />
<Setter Property="TextBlock.Foreground" Value="Black"/>
<Style.Triggers>
<Trigger Property ="IsMouseOver" Value="True">
<Setter Property= "Background" Value="#6d809b"/>
<Setter Property= "TextBlock.Foreground" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
...
Indirect property targeting, that being TextBlock.Foreground is described here http://msdn.microsoft.com/en-us/library/ms742451.aspx. It's basically saying, "hey I couldn't find a property called TextBlock on type button." It works with Background.Color because the Background Property does exist on Button and it's of type ColorBrush which itself has a property of type Color.
I have a button that has a transparent background and a thick white border. When the button detects a mouse enter I see that the background went from the set transparent background to it's default focused color so for that I just set the opacity to 0.2 so that it shows some feed back that it has a focus.
Now here is my dilemma. When I leave the button's bounds there is a small animation that goes from my .2 opacity to 1 before changing the background to the original transparent. I would like to know how to replace this with either a smoother animation so that I don't see the opaque background before it changing to transparent or just have a way to bypass the animation completely and just have it set my values. I see the similar thing happen when the button is focused. It will animate between 0.2 opacity and 1.0 with the default background color. Any ideas would be greatly appreciated.
<Button BorderBrush="White" BorderThickness="1" Width="45" Height="45" >
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value="0.2" />
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Opacity" Value="1.0" />
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Here is a XAML only solution, I think this does what you want...
<Button BorderBrush="White" BorderThickness="1" Width="45" Height="45" Content="1234" >
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Opacity" Value="1.0" />
</Trigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="0.2" To="1"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="0.2" To="0.2"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>