I'm trying to style a ListBoxItem that the item is green when it is selected and lightgreen when the mouse is over the item.
This works, but when an item is selected and I move my mouse over that item, the selected style disappears. How can I fix this ?
<Style x:Key="{x:Type ListBoxItem}"
TargetType="ListBoxItem">
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="SnapsToDevicePixels"
Value="true" />
<Setter Property="OverridesDefaultStyle"
Value="true" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border x:Name="Border"
Margin="0,3,0,3"
SnapsToDevicePixels="true">
<Border.Background>
<SolidColorBrush Color="Transparent" />
</Border.Background>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="SelectionStates">
<VisualState x:Name="Unselected" />
<VisualState x:Name="Selected">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="0" Value="Green" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Textblock"
Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="0" Value="White" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup Name="CommonStates">
<VisualState Name="Normal" />
<VisualState Name="MouseOver">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="0" Value="LightGreen" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<TextBlock x:Name="Textblock"
FontFamily="Segoe UI" Foreground="{StaticResource AlmostWhite}" FontSize="15" Padding="5,7,5,7" VerticalAlignment="Center">
<ContentPresenter />
</TextBlock>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
If using Triggers an option for you, then you could use MultiTriggers to say don't apply MouseOver color when the Item is Selected.
Below is the style with MultiTriggers, and it MouserOver won't override the background when Item is selected.
<Style x:Key="listBoxItemStyle" TargetType="ListBoxItem">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Green" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="IsSelected" Value="False" />
</MultiTrigger.Conditions>
<Setter Property="Background" Value="LightGreen" />
</MultiTrigger>
</Style.Triggers>
</Style>
Not sure, how you can achieve this with VSM, I will be watching this thread for a better answer.
As #Novitchi S mentioned, it would be much simpler defining this Style using basic Triggers:
<Style x:Key="listBoxItemStyle" TargetType="ListBoxItem">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Green" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="LightGreen" />
</Trigger>
</Style.Triggers>
</Style>
Even if you really wanted to use a Storyboard, you could just add it into the Trigger.EnterActions section.
UPDATE >>>
There really is no need to use a MultiTrigger to achieve your requirement either. I probably didn't spot your requirement to keep the selected colour when the mouse is over the item... you just need to reverse the order of the Triggers... the latter one will 'override' the behaviour of the former one:
<Style x:Key="listBoxItemStyle" TargetType="ListBoxItem">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="LightGreen" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Green" />
</Trigger>
</Style.Triggers>
</Style>
Related
so im quite new to Wpf and was trying to animate something like this particular Animation:
Example
I found something like that to make an Colour Animation:
<EventTrigger
RoutedEvent="TextBox.MouseEnter">
<BeginStoryboard>
<Storyboard SlipBehavior="Slip">
<ColorAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="Background.Color"
To="Blue" Duration="00:00:00.2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger
RoutedEvent="TextBox.MouseLeave">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="Background.Color"
To="WhiteSmoke" Duration="00:00:00.2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
Its just change the Color but I want to make it slide from left to right like the example, I know there is Blend to edit those kinda stuff. But I only know how to animate Objects to move but not how to slide the Color From Left to right.
My TextBox style looks like this now, could someone give me a Hint how to manage what I want to get?
<Style x:Key="TextBoxStyle1" TargetType="{x:Type TextBox}">
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
<Setter Property="BorderBrush" Value="{StaticResource TextBox.Static.Border}"/>
<Setter Property="FontSize" Value="8"/>
<Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="AllowDrop" Value="true"/>
<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<Border x:Name="border" Background="White" BorderBrush="#FF7D8683" CornerRadius="5" BorderThickness="0"/>
<ScrollViewer x:Name="PART_ContentHost" Margin="5,0,0,0" VerticalAlignment="Center" />
<Label Margin="5,0,0,0" x:Name="WaterMarkLabel" Content="{TemplateBinding Tag}" VerticalAlignment="Center"
Visibility="Collapsed" Foreground="Gray" FontFamily="Arial"/>
</Grid>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Text" Value=""/>
</MultiTrigger.Conditions>
<Setter Property="Visibility" TargetName="WaterMarkLabel" Value="Visible"/>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="DimGray"/>
</Trigger>
<EventTrigger
RoutedEvent="TextBox.MouseEnter">
<BeginStoryboard>
<Storyboard SlipBehavior="Slip">
<ColorAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="Background.Color"
To="Blue" Duration="00:00:00.2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger
RoutedEvent="TextBox.MouseLeave">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="border"
Storyboard.TargetProperty="Background.Color"
To="WhiteSmoke" Duration="00:00:00.2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsInactiveSelectionHighlightEnabled" Value="true"/>
<Condition Property="IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="SelectionBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
</MultiTrigger>
</Style.Triggers>
</Style>
I have added MouseEnter and MouseLeave event triggers and used DoubleAnimation to set the width:
<Page.Resources>
<SolidColorBrush x:Key="TextBox.Static.Border" Color="#FFABAdB3"/>
<SolidColorBrush x:Key="TextBox.MouseOver.Border" Color="#FF7EB4EA"/>
<SolidColorBrush x:Key="TextBox.Focus.Border" Color="#FF569DE5"/>
<Style x:Key="TextBoxStyle1" TargetType="{x:Type TextBox}">
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
<Setter Property="BorderBrush" Value="{StaticResource TextBox.Static.Border}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="AllowDrop" Value="true"/>
<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border x:Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="True">
<ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.MouseOver.Border}"/>
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.Focus.Border}"/>
</Trigger>
<!-- Now we add the MouseEnter event.-->
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Width" To="200" From="20" Duration="0:0:0:0.5" AccelerationRatio="0.5" DecelerationRatio="0.3"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<!-- Now we add the MouseLeave event.-->
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Width" To="20" Duration="0:0:0:0.5" AccelerationRatio="0.5" DecelerationRatio="0.3"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<!-- That's all the codes we add to the default style.-->
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsInactiveSelectionHighlightEnabled" Value="true"/>
<Condition Property="IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="SelectionBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
</MultiTrigger>
</Style.Triggers>
</Style>
</Page.Resources>
I have a button style which I'm currently making. I want to trigger a smooth animation when the user clicks on the button. I need the two rectangle to be contained within the ControlTemplate as shown below.
The idea is that upon pressing the button, one of the rectangles fades out, and upon releasing it fades back in.
The triggers ARE being hit. I can prove this by adding a simple colour change for the buttons by doing the following before the Trigger.EnterActions:
<Setter TargetName="BackgroundNormal" Property="Fill" Value="Cyan" />
The storyboards seem not to trigger at all regardless of their content.
What am I doing wrong, please?
<Style x:Key="MyButton" TargetType="{x:Type Button}">
<Setter Property="Foreground" Value="{DynamicResource TextParagraphWhiteP1}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontWeight" Value="Light" />
<Setter Property="Background" Value="{DynamicResource Gradient_Playback_ButtonBase}" />
<Setter Property="MinHeight" Value="15" />
<Setter Property="MinWidth" Value="0" />
<Setter Property="Padding" Value="6,2" />
<Setter Property="BorderBrush" Value="Black" />
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Rectangle x:Name="BackgroundDepressed" Fill="Magenta" />
<Rectangle x:Name="BackgroundNormal" Fill="{DynamicResource Gradient_Playback_ButtonBase}" />
</Grid>
<ControlTemplate.Resources>
<Storyboard x:Key="PressDown">
<DoubleAnimation Storyboard.TargetName="BackgroundNormal" Storyboard.TargetProperty="(UIElement.Opacity)" To="0.0" Duration="0:0:0.1" />
</Storyboard>
<Storyboard x:Key="Release">
<DoubleAnimation Storyboard.TargetName="BackgroundNormal" Storyboard.TargetProperty="(UIElement.Opacity)" To="1.0" Duration="0:0:0.35" />
</Storyboard>
</ControlTemplate.Resources>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="true">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource PressDown}" />
</Trigger.EnterActions>
</Trigger>
<Trigger Property="IsPressed" Value="false">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource Release}" />
</Trigger.EnterActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
In my application, I have a custom button style and template that has a couple states based on XAML triggers:
<Style x:Key="UniversalButton" TargetType="{x:Type Button}">
<Setter Property="Cursor" Value="Hand" />
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Background" Value="#FFD7D7D7" />
<Setter Property="BorderBrush" Value="#FF999999" />
<Setter Property="Foreground" Value="#FF666666" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<ControlTemplate.Resources>
<Style x:Key="ButtonBorder" TargetType="{x:Type Border}">
<Setter Property="CornerRadius" Value="3" />
<Setter Property="BorderThickness" Value="0,0,0,2" />
<Setter Property="SnapsToDevicePixels" Value="True" />
</Style>
<Style x:Key="ButtonContent" TargetType="{x:Type ContentPresenter}">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="TextBlock.TextAlignment" Value="Center" />
<Setter Property="Margin" Value="8,7,8,8" />
<Setter Property="RecognizesAccessKey" Value="True" />
<Setter Property="SnapsToDevicePixels" Value="True" />
</Style>
</ControlTemplate.Resources>
<ControlTemplate.Triggers>
<Trigger Property="ContextMenu.IsOpen" Value="True">
<Setter Property="Opacity" Value="0.8" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="IsEnabled" Value="True" />
</MultiTrigger.Conditions>
<MultiTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="0.8" Duration="0:0:0.1" />
</Storyboard>
</BeginStoryboard>
</MultiTrigger.EnterActions>
<MultiTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.1" />
</Storyboard>
</BeginStoryboard>
</MultiTrigger.ExitActions>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.6" />
</Trigger>
</ControlTemplate.Triggers>
<Border Style="{DynamicResource ButtonBorder}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
Padding="{TemplateBinding Padding}"
Opacity="{TemplateBinding Opacity}">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<ContentPresenter Style="{DynamicResource ButtonContent}"
TextBlock.FontWeight="{TemplateBinding FontWeight}"
TextBlock.Foreground="{TemplateBinding Foreground}"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The specific instance of the button in question has a command with a CanExecute based on the selections of an ItemsControl in the view. When I toggle my selections, including those that are meant to disable the button, things work fine. The button becomes semi-transparent as I have called for in the XAML trigger for IsEnabled.
The problem starts when I mouse over the button, activating the storyboards above. After this happens, changing the selections to a state in which the button is disabled leaves the button fully opaque, regardless of the state of IsEnabled/CanExecute.
Through extensive debugging, I've determined that the issue is not caused by the CanExecute as previously thought, and that it must be linked to the IsMouseOver trigger. I've exhausted all of my XAML knowledge in trying to figure this conflict out and I'd be very grateful for help.
Thanks in advance!
I believe that the issue is caused by Dependency Property value precedence in WPF. In this case the animation (Timeline) has the default FillBehavior of FillBehavior.HoldEnd. After the animation finishes all the attempts to change the value (the Opacity property) should have a higher precedence. From the link you can see only system coercing the value can override the animation-based value (even locally setting such as by assignment directly in codebehind cannot override this).
That's why your template Trigger (whose precedence is 7) cannot override the current animated value. There are some solutions to this but I think you should use all storyboard in your triggers (instead of using a setter). If you don't want any animation, just set Duration to zero:
<Trigger Property="ContextMenu.IsOpen" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
To=".8" Duration="0:0:0"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<!-- similar for ExitActions -->
</Trigger>
<!-- -->
<Trigger Property="IsEnabled" Value="False">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
To=".6" Duration="0:0:0"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<!-- similar for ExitActions -->
</Trigger>
Using Storyboard this way is also good for maintenance. That's when you want to add some animation to the property value change, then you already have the Storyboard there and you can just add more options or animations...
PS: Don't be afraid of long XAML code. It's the nature and a characteristic of XAML code. However as a trade-off, we have more controls over the behaviors and effects.
I just have the same problem.
After several tests, I found the ExitActions of IsEnabled trigger, though finished its execution, would still somehow "stays" there and blocks the upcoming animation.
I haven't figured out the exact reason behind it, yet emprically, removing that storyboard before beginning another seems to solve the problem.
Codes like:
<Trigger Property="ContextMenu.IsOpen" Value="True">
<Trigger.EnterActions>
<RemoveStoryboard BeginStoryboardName="someStoryboard" />
<BeginStoryboard>
<!-- animation here -->
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Trigger.ExitActions>
<BeginStoryboard x:Name="someStoryboard">
</Trigger>
I have a ListView styled using the WhistlerBlue.xaml resource dictionary, as downlaoded from Codeplex: WPF DataGrid Themes from Silverlight.
I want alternating (odd & even) rows to have a different background colour.
I have added the following code to the default WhistlerBlue ListViewItem style (within the ControlTemplate.Triggers section):
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Background" Value="White"></Setter>
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="AliceBlue"></Setter>
</Trigger>
I have also set the ListView style's AlternatingCount property to 2, but the alternating style triggers are still not working.
Any pointers would be greatly appreciated.
I've pasted the complete ListViewItemStyle below.
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="FocusVisualStyle" Value="{StaticResource ListViewItemFocusVisual}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Margin" Value="0,0,0,1" />
<Setter Property="Padding" Value="5,2,5,2" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Foreground" Value="{StaticResource OutsideFontColor}"/>
<Setter Property="Padding" Value="3" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<ControlTemplate.Resources>
<Storyboard x:Key="HoverOn">
<DoubleAnimation Duration="00:00:00.00" Storyboard.TargetName="BackgroundGradientOver" Storyboard.TargetProperty="Opacity" To="0.73"/>
</Storyboard>
<Storyboard x:Key="HoverOff">
<DoubleAnimation Duration="00:00:00.00" Storyboard.TargetName="BackgroundGradientOver" Storyboard.TargetProperty="Opacity" To="0"/>
</Storyboard>
<Storyboard x:Key="SelectedOn">
<DoubleAnimation Duration="00:00:00.00" Storyboard.TargetName="BackgroundGradientSelected" Storyboard.TargetProperty="Opacity" To="0.84"/>
<DoubleAnimation Duration="00:00:00.00" Storyboard.TargetName="BackgroundGradientSelectedDisabled" Storyboard.TargetProperty="Opacity" To="1"/>
</Storyboard>
<Storyboard x:Key="SelectedOff">
<DoubleAnimation Duration="00:00:00.00" Storyboard.TargetName="BackgroundGradientSelected" Storyboard.TargetProperty="Opacity" To="0"/>
<DoubleAnimation Duration="00:00:00.00" Storyboard.TargetName="BackgroundGradientSelectedDisabled" Storyboard.TargetProperty="Opacity" To="0"/>
</Storyboard>
</ControlTemplate.Resources>
<Border SnapsToDevicePixels="true" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="2" x:Name="border">
<Grid Margin="0">
<Rectangle x:Name="BackgroundGradientOver" Fill="{StaticResource hoverGradient}" Stroke="{StaticResource hoverStroke}" RadiusX="2" RadiusY="2" Opacity="0"/>
<Rectangle x:Name="BackgroundGradientSelectedDisabled" Fill="{StaticResource grayGradient}" Stroke="#7F8E8F8F" RadiusX="2" RadiusY="2" Opacity="0"/>
<Rectangle x:Name="BackgroundGradientSelected" Fill="{StaticResource BtnOverFill}" Stroke="{StaticResource selectedStroke}" RadiusX="2" RadiusY="2" Opacity="0"/>
<Rectangle x:Name="BackgroundHighlight" Margin="1" Stroke="#A0FFFFFF" RadiusX="1" RadiusY="1"/>
<GridViewRowPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Margin="0,2,0,2" VerticalAlignment="Stretch" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Background" Value="White"></Setter>
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="AliceBlue"></Setter>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource HoverOff}" x:Name="HoverOff_BeginStoryboard"/>
</Trigger.ExitActions>
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource HoverOn}"/>
</Trigger.EnterActions>
</Trigger>
<Trigger Property="IsSelected" Value="true">
<Trigger.ExitActions>
<BeginStoryboard x:Name="SelectedOff_BeginStoryboard" Storyboard="{StaticResource SelectedOff}"/>
</Trigger.ExitActions>
<Trigger.EnterActions>
<BeginStoryboard x:Name="SelectedOn_BeginStoryboard" Storyboard="{StaticResource SelectedOn}"/>
</Trigger.EnterActions>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource DisabledForegroundBrush}" />
<Setter Property="Visibility" TargetName="BackgroundGradientSelected" Value="Hidden"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true" />
<Condition Property="Selector.IsSelectionActive" Value="false" />
</MultiTrigger.Conditions>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Apparently the ListViewItem ControlTemplate was overriding the style triggers for alternate row colours.
Since I was not using the storyboards in the ControlTemplate (I had set their Duration to 0), I solved the problem by just using Style Triggers, without styling the Template, as shown below.
<Style TargetType="{x:Type ListViewItem}" x:Key="ListViewItemStyle">
<Setter Property="FocusVisualStyle" Value="{StaticResource ListViewItemFocusVisual}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Padding" Value="5,2,5,2" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Height" Value="23px" />
<Setter Property="Foreground" Value="{StaticResource OutsideFontColor}"/>
<Style.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Background" Value="White" />
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="AliceBlue" />
<Setter Property="BorderBrush" Value="AliceBlue" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{StaticResource BtnOverFill}" />
<Setter Property="BorderBrush" Value="{StaticResource selectedStroke}" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="#FFbbe9fd" />
</Trigger>
</Style.Triggers>
</Style>
I know this doesn't solve the problem if the ContolTemplate needs to be styled, but at least this was enough to satisfy my requirements.
Hope it helps somebody in the future.
At ExpressionDark.xaml for example:
find this: <Style TargetType="{x:Type ListViewItem}">
and find <Rectangle x:Name="Background"..
change the property value Fill to Fill="{TemplateBinding Background}"
and, inside the <ControlTemplate.Triggers> add this:
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="#FF474A51"></Setter>
</Trigger>
Hope this helps anyone, else as beginner for wpf i am having hard time finding things specially i am on vb.net, very hard to get direct sample codes using mvvm, etc. :( cruel world.
I have a WPF project with a border using the following style. The plan is to get the glow effect to fade in when the mouse moves over the border, and fade out when it leaves.
<Style x:Key="BorderGlow" TargetType="Border">
<Style.Resources>
<Storyboard x:Key="GlowOn">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(DropShadowEffect.Opacity)">
<SplineDoubleKeyFrame KeyTime="0:0:0.3" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="GlowOff">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(DropShadowEffect.Opacity)">
<SplineDoubleKeyFrame KeyTime="0:0:0.3" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Style.Resources>
<Setter Property="CornerRadius" Value="6,1,6,1" />
<Setter Property="BorderBrush" Value="{StaticResource SelectedBorder}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Background" Value="{StaticResource DeselectedBackground}" />
<Setter Property="RenderTransformOrigin" Value="0.5,0.5" />
<Setter Property="TextBlock.Foreground" Value="{StaticResource SelectedForeground}" />
<Setter Property="RenderTransform">
<Setter.Value>
<RotateTransform Angle="90"/>
</Setter.Value>
</Setter>
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="0" BlurRadius="8" Color="#FFB0E9EF"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource GlowOn}"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource GlowOff}"/>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
The problem is, nothing happens! The animation works if I change the "DropShadowEffect" to "UIElement" in the Storyboard TargetProperty, but this fades the entire control.
How do I fade just the DropShadowEffect?
A couple of points to note
1) You need to be targeting an actual property of Border - You are in effect trying to target the value (DropShadowEffect) of the Effect property, not the property itself.
2) You need to sort the syntax of the PropertyPath.
Change your Storyboard.Target property to the following and you should be fine:
Storyboard.TargetProperty="(Effect).Opacity"
EDIT Working code as noted in comment:
<Border BorderThickness="10" Height="100" Width="100">
<Border.BorderBrush>
<SolidColorBrush Color="Red"></SolidColorBrush>
</Border.BorderBrush>
<Border.Style>
<Style TargetType="Border">
<Style.Resources>
<Storyboard x:Key="GlowOn">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetProperty="(Effect).Opacity">
<SplineDoubleKeyFrame KeyTime="0:0:0.3" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="GlowOff">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetProperty="(Effect).Opacity">
<SplineDoubleKeyFrame KeyTime="0:0:0.3" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Style.Resources>
<Setter Property="CornerRadius" Value="6,1,6,1" />
<!--<Setter Property="BorderBrush"
Value="{StaticResource SelectedBorder}" />-->
<Setter Property="BorderThickness" Value="1" />
<!--<Setter Property="Background"
Value="{StaticResource DeselectedBackground}" />-->
<Setter Property="RenderTransformOrigin" Value="0.5,0.5" />
<!--<Setter Property="TextBlock.Foreground"
Value="{StaticResource SelectedForeground}" />-->
<Setter Property="RenderTransform">
<Setter.Value>
<RotateTransform Angle="90"/>
</Setter.Value>
</Setter>
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="20"
BlurRadius="8"
Color="#FFB0E9EF"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard
Storyboard="{StaticResource GlowOn}"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard
Storyboard="{StaticResource GlowOff}"/>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
This is a followup to Simon's answer where I have a ListView where the Template item of the ListViewItem had a DropShadow on a Grid. Long story short, because one is overriding the ListViewItem, the selected item and the hover no longer work. To get those to work I had to modify the Opacity and there are two ways to access the Effect depending on where one is; which I show below...here are Full example of the two snippets:
Set during Selection
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true" />
<Condition Property="Selector.IsSelectionActive" Value="true" />
</MultiTrigger.Conditions>
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect Opacity="1"/>
</Setter.Value>
</Setter>
</MultiTrigger>
</Style.Triggers>
Set for Grid.Triggers
<Grid Background="GhostWhite">
<Grid.Effect>
<DropShadowEffect Opacity="0" />
</Grid.Effect>
<GridViewRowPresenter Content="{TemplateBinding Content}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
<Grid.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames
BeginTime="00:00:00"
Storyboard.TargetProperty="(Effect).Opacity">
<SplineDoubleKeyFrame KeyTime="0:0:0.1" Value=".2"/>
<SplineDoubleKeyFrame KeyTime="0:0:0.4" Value=".6"/>
<SplineDoubleKeyFrame KeyTime="0:0:0.6" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>