I have two DataTriggers binded to a property (Side) but only one storyboard could be started (the one in the last DataTriggers).
Why ?
I feel like the last storyboard override the first one
<Border x:Name="layout" Background="Transparent" BorderBrush="#BAC8CE" BorderThickness="1" CornerRadius="5">
<Border.Style>
<Style TargetType="{x:Type Border}">
<Style.Triggers>
<DataTrigger Binding="{Binding Side}" Value="Up">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"
Duration="00:00:01"
From="Transparent"
To="Green"/>
<ColorAnimation Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"
Duration="00:00:00.5"
From="Green"
To="Transparent"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
<DataTrigger Binding="{Binding Side}" Value="Down">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"
Duration="00:00:01"
From="Transparent"
To="Red"/>
<ColorAnimation Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"
Duration="00:00:00.5"
From="Red"
To="Transparent"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
I would suggest stopping your storyboard before the other one runs:
<Border x:Name="layout" Background="Transparent" BorderBrush="#BAC8CE" BorderThickness="1" CornerRadius="5">
<Border.Style>
<Style TargetType="{x:Type Border}">
<Style.Triggers>
<DataTrigger Binding="{Binding Side}" Value="Up">
<DataTrigger.EnterActions>
<StopStoryboard BeginStoryboardName="BeginStoryboardTwo" />
<BeginStoryboard x:Name="BeginStoryboardOne">
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"
Duration="00:00:01"
From="Transparent"
To="Green"/>
<ColorAnimation Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"
Duration="00:00:00.5"
From="Green"
To="Transparent"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
<DataTrigger Binding="{Binding Side}" Value="Down">
<DataTrigger.EnterActions>
<StopStoryboard BeginStoryboardName="BeginStoryboardOne" />
<BeginStoryboard x:Name="BeginStoryboardTwo" >
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"
Duration="00:00:01"
From="Transparent"
To="Red"/>
<ColorAnimation Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"
Duration="00:00:00.5"
From="Red"
To="Transparent"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<TextBlock Text="Hello World!" />
</Border>
try following solution, put your second datatrigger enter action at the first datatrigger exit action
<Border x:Name="layout"
Grid.Row="1"
Background="Transparent"
BorderBrush="#BAC8CE"
BorderThickness="1"
CornerRadius="5">
<Border.Style>
<Style TargetType="{x:Type Border}">
<Style.Triggers>
<DataTrigger Binding="{Binding Side, ElementName=uc, Mode=OneWay}"
Value="Up">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"
Duration="00:00:05"
From="Transparent"
To="Green" />
<ColorAnimation Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"
Duration="00:00:00.5"
From="Green"
To="Transparent" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"
Duration="00:00:05"
From="Transparent"
To="Red" />
<ColorAnimation Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"
Duration="00:00:00.5"
From="Red"
To="Transparent" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
hope this helps
Related
I have a MenuItem style , it works great but when I select (click) on a menu item it doesn't fire "IsMouseOver" or "IsHighlighted" again.
I tried to fix it by using IsKeyboardFocused but it kills IsPressed on the other side so I can't use it too.
here's my style code :
<Style TargetType="{x:Type MenuItem}" x:Key="MyCustomMenuItem">
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="FontFamily" Value="{DynamicResource MenuFontFamily}"/>
<Setter Property="Focusable" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Border x:Name="brd" Background="{StaticResource MainBrush}" >
<Grid>
<ContentPresenter Content="{TemplateBinding Header}" Margin="10,3,10,3" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<Popup x:Name="PART_Popup" Placement="Right" AllowsTransparency="True" Focusable="False" IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}">
<Border x:Name="SubMenuBorder" BorderBrush="{DynamicResource KeyColor}" BorderThickness="1" Background="{DynamicResource MainBrushTransparent}" Padding="2">
<ScrollViewer x:Name="SubMenuScrollViewer" Style="{DynamicResource {ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}}">
<Grid RenderOptions.ClearTypeHint="Enabled">
<Canvas HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
<Rectangle x:Name="OpaqueRect" Fill="{DynamicResource MainBrushTransparent}" Height="{Binding ActualHeight, ElementName=SubMenuBorder}" Width="{Binding ActualWidth, ElementName=SubMenuBorder}"/>
</Canvas>
<ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Cycle" Grid.IsSharedSizeScope="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" KeyboardNavigation.TabNavigation="Cycle"/>
</Grid>
</ScrollViewer>
</Border>
</Popup>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsHighlighted" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="brd" Duration="0:0:0.300" To="#349E7E" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" />
<ColorAnimation Duration="0:0:0.300" To="#FFEAEAEA" Storyboard.TargetProperty="Foreground.Color" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="brd" Duration="0:0:0.300" To="#2C2C2C" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" />
<ColorAnimation Duration="0:0:0.300" To="#FF8B8B8B" Storyboard.TargetProperty="Foreground.Color" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="brd" Duration="0:0:0.300" To="#FF34008D" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="brd" Duration="0:0:0.300" To="#2C2C2C" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsSubmenuOpen" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="brd" Duration="0:0:0.300" To="#349E7E" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" />
<ColorAnimation Duration="0:0:0.300" To="#FFEAEAEA" Storyboard.TargetProperty="Foreground.Color" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="brd" Duration="0:0:0.300" To="#2C2C2C" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" />
<ColorAnimation Duration="0:0:0.300" To="#FF8B8B8B" Storyboard.TargetProperty="Foreground.Color" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
How can I make it work after pressing menu ?
If I remove press trigger it works fine :\
Replace the <BeginStoryboard> element in the ExitAction for the IsHighlighted trigger with a RemoveStoryboard and set the FillBehavior property of the IsPressed animation to Stop:
<Trigger Property="IsHighlighted" Value="True">
<Trigger.EnterActions>
<BeginStoryboard x:Name="sb1">
<Storyboard>
<ColorAnimation Storyboard.TargetName="brd" Duration="0:0:0.300" To="#349E7E" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" />
<ColorAnimation Duration="0:0:0.300" To="#FFEAEAEA" Storyboard.TargetProperty="Foreground.Color" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<RemoveStoryboard BeginStoryboardName="sb1" />
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Trigger.EnterActions>
<BeginStoryboard x:Name="sb2">
<Storyboard>
<ColorAnimation Storyboard.TargetName="brd" Duration="0:0:0.300" To="#FF34008D"
FillBehavior="Stop"
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
I want my grid to show up on button click, and hide when clicked again. When i add one DataTrigger to grid it works fine, however for two of them it works only on the latter one and when it's supossed to play animation for the first one, it just basicly does nothing. Here is the code
<Grid Background="Red" HorizontalAlignment="Left" VerticalAlignment="Top">
<Grid.Style>
<Style TargetType="Grid">
<Style.Triggers>
<DataTrigger Binding="{Binding Open}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:1" Storyboard.TargetProperty="Width" From="0" To="300"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
<DataTrigger Binding="{Binding Open}" Value="False">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:1" Storyboard.TargetProperty="Width" From="300" To="0"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
<Button />
</Grid>
And my ViewModel
public bool Open
{
get
{
return _open;
}
set
{
_open = value;
RaisePropertyChanged("Open");
}
}
public RelayCommand OpenButtonClicked
{
get;
private set;
}
private bool _open;
public AppMenuViewModel() : base()
{
_open = false;
OpenButtonClicked = new RelayCommand(() => Open = !Open);
}
Where is the issue, and if there is none, what can I do to achieve what i want?
Your problem is, that animation doesn't stop. Add FillBehavior="Stop" to the animation and you will get what you are after.
<Style TargetType="Grid">
<Style.Triggers>
<DataTrigger Binding="{Binding Open}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:1" Storyboard.TargetProperty="Width" From="0" To="300" FillBehavior="Stop"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
<DataTrigger Binding="{Binding Open}" Value="False">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:1" Storyboard.TargetProperty="Width" From="300" To="0" FillBehavior="Stop"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
SliderMenu in Youtube
I can't do something similar to this video, the animation doesn't stop and the menu always flashes. Here's my XAML:
<StackPanel.Style>
<Style TargetType="StackPanel">
<Style.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation Storyboard.TargetProperty="Margin"
From="-70,0,0,0" To="15,0,15,0"
DecelerationRatio=".8" Duration="0:0:0.7"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation Storyboard.TargetProperty="Margin"
From="15,0,15,0" To="-70,0,0,0"
DecelerationRatio=".8" Duration="0:0:0.7"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
What's the problem with it?
The flickering is happening because as soon as the StackPanel starts animating, it moves itself out of the way (of the mouse cursor), causing the other animation to start. I don't see you full code, so here are a couple of pointers to improve your code.
Make sure the entire menu is hittest-visible (e.g. by setting a background)
Don't use two triggers, use one trigger with enter and exit-triggers
Avoid the margin on the left - it can cause the same kind of flickering again.
<StackPanel Background="Blue" Width="100" HorizontalAlignment="Left">
<StackPanel.Style>
<Style TargetType="StackPanel">
<Setter Property="Margin" Value="-70,0,0,0"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation Storyboard.TargetProperty="Margin"
From="-70,0,0,0" To="0,0,0,0"
DecelerationRatio=".8" Duration="0:0:0.7"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation Storyboard.TargetProperty="Margin"
From="0,0,0,0" To="-70,0,0,0"
DecelerationRatio=".8" Duration="0:0:0.7"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
<Button Width="100" Height="25"></Button>
</StackPanel>
Result:
In my application I have the following XAML-Code to animate the SearchInputView a bit.
<Grid Grid.Row="1" HorizontalAlignment="Right" Grid.RowSpan="4" Panel.ZIndex="200" VerticalAlignment="Top"
Margin="0,-29,6,0">
<Grid.Resources>
<Duration x:Key="SearchAnimationDuration">0:0:0.4</Duration>
<system:Double x:Key="Hidden">0.0</system:Double>
<system:Double x:Key="Visible">1.0</system:Double>
<system:Double x:Key="Transparent">0.5</system:Double>
<Style TargetType="{x:Type view:SearchInputView}">
<Style.Triggers>
<Trigger Property="Visibility" Value="Visible">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="{StaticResource Hidden}" To="{StaticResource Visible}"
Duration="{StaticResource SearchAnimationDuration}"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="{StaticResource Transparent}" To="{StaticResource Visible}"
Duration="{StaticResource SearchAnimationDuration}"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="{StaticResource Visible}" To="{StaticResource Transparent}"
Duration="{StaticResource SearchAnimationDuration}"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<view:SearchInputView Visibility="{Binding DataContext.SearchIsVisible, Mode=TwoWay, Converter={converter:BoolToVisibilityConverter}, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"/>
</Grid>
The SearchInputView is located in right upper corner of my window. Now I want the control, if the mouse is not over, to fade out of the screen a bit so that only the half of the control is in the visible area. I tried it with the following DoubleAnimation in the ExitActions:
<DoubleAnimation Storyboard.TargetProperty="Margin.Left" To="50" Duration="0:0:0.4"/>
Now when the mouse leaves the control my application crashed immediately.
How can I move my control when the mouse leaves it?
Margin.Left is not DependencyProperty so you cannot animate only left. You can either use ThicknessAnimation to animate whole margin or use TranslateTransform as RenderTransform and animate that
<Style TargetType="{x:Type view:SearchInputView}">
<Setter Property="RenderTransform">
<Setter.Value>
<TranslateTransform X="0" Y="0"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="{StaticResource Transparent}" To="{StaticResource Visible}" Duration="{StaticResource SearchAnimationDuration}"/>
<DoubleAnimation Storyboard.TargetProperty="RenderTransform.X" To="0" Duration="0:0:0.4"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="{StaticResource Visible}" To="{StaticResource Transparent}" Duration="{StaticResource SearchAnimationDuration}"/>
<DoubleAnimation Storyboard.TargetProperty="RenderTransform.X" To="50" Duration="0:0:0.4"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
this is part of my code, i already search it on google but no one know what i mean.
<Label HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Width="30" Height="30" Content="" FontFamily="FontAwesome" HorizontalAlignment="Right" VerticalAlignment="Center">
<Label.Style>
<Style TargetType="{x:Type Label}">
<Style.Triggers>
<Trigger Property="Label.IsMouseOver" Value="True">
<Setter Property="Label.Background" Value="Yellow" />
</Trigger>
</Style.Triggers>
</Style>
</Label.Style>
</Label>
You can try using EventTrigger in this case. If's of course longer but it's the simplest approach using pure standard XAML (not any custom):
<Label HorizontalContentAlignment="Center" VerticalContentAlignment="Center"
Width="30" Height="30" Content="Clgt?" FontFamily="FontAwesome"
HorizontalAlignment="Right" VerticalAlignment="Center">
<Label.Style>
<Style TargetType="{x:Type Label}">
<Style.Triggers>
<EventTrigger RoutedEvent="MouseLeftButtonDown">
<BeginStoryboard>
<Storyboard>
<ColorAnimation To="Yellow" Duration="0"
Storyboard.TargetProperty="Background.Color"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeftButtonUp">
<BeginStoryboard>
<Storyboard>
<ColorAnimation To="Transparent" Duration="0"
Storyboard.TargetProperty="Background.Color"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</Label.Style>
</Label>
It's even better to use RemoveStoryboard action when the MouseLeftButtonUp like this:
<Style.Triggers>
<EventTrigger RoutedEvent="MouseLeftButtonDown">
<BeginStoryboard Name="bg">
<Storyboard>
<ColorAnimation To="Yellow" Duration="0"
Storyboard.TargetProperty="Background.Color"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeftButtonUp">
<RemoveStoryboard BeginStoryboardName="bg"/>
</EventTrigger>
</Style.Triggers>