I am trying to animate a canvas opacity on mouse enter, but i cannot find the equivalent event to animate when a mouse leaves the canvas.
Here's a simple reproducible example with mouse animation enter/leave on a canvas:
<Canvas x:Name="canvas" Width="100" Height="100" Background="Blue">
<Canvas.Style>
<Style TargetType="Canvas">
<Setter Property="Opacity" Value="0.1"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<StopStoryboard BeginStoryboardName="fadeout"/>
<BeginStoryboard x:Name="fadein">
<Storyboard>
<DoubleAnimation From="0.1" To="1.0" Duration="00:00:01" Storyboard.TargetProperty="Opacity" FillBehavior="HoldEnd"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Trigger.EnterActions>
<StopStoryboard BeginStoryboardName="fadein"/>
<BeginStoryboard x:Name="fadeout">
<Storyboard>
<DoubleAnimation From="1" To="0.1" Duration="00:00:01" Storyboard.TargetProperty="Opacity" FillBehavior="HoldEnd"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
</Canvas.Style>
</Canvas>
Related
I have a style trigger on my Buttons IsEnabled property that fires and wiggles my buttons when set to True. This works fine if I disable and then re-enable the button from the code behind (MVVM) once the application has loaded and running. However, the trigger does not fire on initial load. So all my buttons that are enabled by default do not wiggle. What can I do to make the trigger work on load?
Here is my Style from my App.xaml
<Setter Property="RenderTransformOrigin" Value="0.5,0" />
<Setter Property="RenderTransform">
<Setter.Value>
<RotateTransform />
</Setter.Value>
</Setter>
<Style TargetType="{x:Type Button}" x:Key="btnDefaultStyle">
<Style.Triggers>
<Trigger Property="IsEnabled" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard TargetProperty="RenderTransform.Angle" RepeatBehavior="Forever">
<DoubleAnimation From="0" To="-5" BeginTime="0:0:0:5.00" Duration="0:0:0.05"/>
<DoubleAnimation From="-5" To="0" BeginTime="0:0:0:5.05" Duration="0:0:0.05"/>
<DoubleAnimation From="0" To="4" BeginTime="0:0:0:5.10" Duration="0:0:0.05"/>
<DoubleAnimation From="4" To="0" BeginTime="0:0:0:5.15" Duration="0:0:0.05"/>
<DoubleAnimation From="0" To="-3" BeginTime="0:0:0:5.20" Duration="0:0:0.05"/>
<DoubleAnimation From="-3" To="0" BeginTime="0:0:0:5.25" Duration="0:0:0.05"/>
<DoubleAnimation From="0" To="2" BeginTime="0:0:0:5.30" Duration="0:0:0.05"/>
<DoubleAnimation From="2" To="0" BeginTime="0:0:0:5.35" Duration="0:0:0.05"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard TargetProperty="RenderTransform.Angle">
<DoubleAnimation From="0" To="0" BeginTime="0:0:0:0" Duration="0:0:0.0"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource btnDefaultStyle}" />
EventTriggers RoutedEvent, I.e. RoutedEvent="Window.Loaded" is no use as it overrides the Property IsEnable event, and therefore my disabled buttons also wiggle.
Use DataTrigger like below :
<DataTrigger Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
...
</BeginStoryboard>
</DataTrigger.EnterActions>
...
</DataTrigger>
<DataTrigger Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="False">
...
</DataTrigger>
This works at load time too.
I have a ListBox with customized item's style. I want the item to grow a bit when selected, and go back to its original size when deselected. I've tried several solutions but none seemed to work. I think the problem lies in the proper setting of Storyboard.TargetProperty.
My current XAML looks like this:
...
<ListBox.Resources>
<Style TargetType="{x:Type ListBoxItem}">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="LayoutTransform.(ScaleTransform.ScaleX)" To="1.2" Duration="0:0:.3" AutoReverse="True"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
</ListBox.Resources>
...
My final code (with answers applied):
...
<ListBox.Resources>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="RenderTransformOrigin" Value="0.5,0.5" />
<Setter Property="RenderTransform">
<Setter.Value>
<ScaleTransform />
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleX" To="1.1" Duration="0:0:.1" />
<DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY" To="1.1" Duration="0:0:.1" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleX" To="1.0" Duration="0:0:.1" />
<DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY" To="1.0" Duration="0:0:.1" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
</ListBox.Resources>
...
Try using following code:
...
<ListBox.Resources>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="LayoutTransform">
<Setter.Value>
<ScaleTransform x:Name="scaleTransform" />
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="LayoutTransform.ScaleX" To="1.2" Duration="0:0:.3" AutoReverse="True"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
</ListBox.Resources>
...
I have a textblock that currently has a trigger that sets the foreground colour when the mouse enters and back to the default when it leaves. The problem I have is that I would also like the mouse pointer to change I currently have the following
<Style TargetType="TextBlock" x:Key="FlatStyleButton">
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background" Value="#FF333333" />
<Style.Triggers>
<EventTrigger RoutedEvent="UIElement.MouseEnter">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="0:0:0.3" Storyboard.TargetProperty="Foreground.Color" To="CornflowerBlue" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="UIElement.MouseLeave">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="0:0:0.3" Storyboard.TargetProperty="Foreground.Color" To="White" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
I have tried adding <Setter Property="Cursor" Value="Hand"></Setter> to various places but it never seems to work
Sorry guys Proper school boy error on my part im afraid, what I was trying would have worked but I was modifiying in the wrong resource file. So if anyone else is intrested the answer was:
<Style TargetType="TextBlock" x:Key="FlatStyleButton">
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background" Value="#FF333333" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand" />
</Trigger>
<EventTrigger RoutedEvent="UIElement.MouseEnter">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="0:0:0.3" Storyboard.TargetProperty="Foreground.Color" To="CornflowerBlue" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="UIElement.MouseLeave">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="0:0:0.3" Storyboard.TargetProperty="Foreground.Color" To="White" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
I have the following (simplified) ControlTemplate:
<ControlTemplate x:Key="ImageButtonTemplate" TargetType="{x:Type controls:ImageButton}">
<Grid x:Name="Grid">
<Border [StuffRemoved]/>
<StackPanel [StuffRemoved]>
<Image [StuffRemoved] />
<ContentPresenter [StuffRemoved] />
</StackPanel>
<Grid.RenderTransform>
<ScaleTransform x:Name="ImgBtnScale"/>
</Grid.RenderTransform>
</Grid>
<ControlTemplate.Triggers>
<!-- problem here! -->
<Trigger Property="IsPressed" Value="True">
<Trigger.Setters>
<Setter TargetName="ImgBtnScale" Property="ScaleX" Value="0.9"/>
<Setter TargetName="ImgBtnScale" Property="ScaleY" Value="0.9"/>
</Trigger.Setters>
</Trigger>
<!-- rest of the stuff works okay-->
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="ImgBtnScale" Storyboard.TargetProperty="ScaleX"
To="1.2" Duration="0:0:0.1"/>
<DoubleAnimation Storyboard.TargetName="ImgBtnScale" Storyboard.TargetProperty="ScaleY"
To="1.2" Duration="0:0:0.1"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="ImgBtnScale" Storyboard.TargetProperty="ScaleX"
To="1" Duration="0:0:0.1"/>
<DoubleAnimation Storyboard.TargetName="ImgBtnScale" Storyboard.TargetProperty="ScaleY"
To="1" Duration="0:0:0.1"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
It doesn't compile, saying that:
Cannot find the target 'ImgBtnScale'. (The target must appear before any Setters, Triggers or Conditions that use it.)
So how do I access ImgBtnScale?
You cannot access it by name because ScaleTransform is not an element in the visual tree, it is just a value of a property of an element (Grid).
What you can do instead is to access the property of the transformation via the parent element where it is defined. For example:
<DoubleAnimation Storyboard.TargetName="Grid" Storyboard.TargetProperty="RenderTransform.(ScaleTransform.ScaleX)" .../>
I think, the problem, is that ScaleTransform is not a Visual element. So it can`t be found in the VisualTree. You should try to set trigger on the grid and change the whole ScaleTransform.
This style correctly fades my toolbar in or out based on the changing of a ViewModel Property:
<Style x:Key="PageToolBarStyle" TargetType="Border">
<Style.Triggers>
<DataTrigger Binding="{Binding PageToolBarVisible}" Value="true">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="Opacity"
From="0.0"
To="1.0"
Duration="0:0:2"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="Opacity"
From="1.0"
To="0.0"
Duration="0:0:2"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
<Trigger Property="Opacity" Value="0">
<Setter Property="Visibility" Value="Collapsed"/>
</Trigger>
</Style.Triggers>
</Style>
However, when the application loads the status of the toolbar (faded out or in) is not in sync with the value of the ViewModel property (true or false). So I want to force this style to be executed upon loading the window, what is the syntax to do this, here is pseudo code of what I want to do:
<Window.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<EventTrigger.Actions>
<!-- PSEUDO-CODE: -->
<ExecuteTriggerStyle StyleToExecute="{StaticResource PageToolBarStyle}"/>
</EventTrigger.Actions>
</EventTrigger>
</Window.Triggers>