WPF Animations Not Working In Items Control - wpf

Below is a ItemsControl that I have defined with a DataTemplate. The trouble I am having is getting the Animations to play. In it's current form the Checkbox's show correctly and the Border changes to Blue when you mouse over each item but when you mouse out the border stays blue. Reordering the triggers collection makes different actions work or break and if I remove the animations and replace them with Setters then things work as expected. What am I missing here? Any help would be very much appreciated - thanks.
<ItemsControl ItemsSource="{Binding ToolBarsBackingStore}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Name="OutterBorder"
BorderThickness="1"
CornerRadius="5"
Background="{StaticResource StaticBackgroundBrush}"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Border.BorderBrush>
<SolidColorBrush x:Name="HighlightBorder"
Color="{StaticResource StaticBackground}" />
</Border.BorderBrush>
<StackPanel Orientation="Horizontal"
Height="16">
<CheckBox Name="ShowCheck"
Style="{StaticResource ToolTrayMenuCheckBoxStyle}"
Margin="3 0 0 0"
IsHitTestVisible="False"
IsChecked="{Binding Path=Visibility,
Converter={StaticResource VisibilityToCheckedConverter}}">
<CheckBox.Foreground>
<SolidColorBrush x:Name="CheckColor"
Color="{StaticResource StaticBackground}" />
</CheckBox.Foreground>
</CheckBox>
<TextBlock Width="80"
Margin="10 0 0 0"
Text="{Binding Path=Name,
Mode=OneTime}"
TextAlignment="Left"
TextTrimming="CharacterEllipsis"
SnapsToDevicePixels="True"
Foreground="White" />
</StackPanel>
</Border>
<DataTemplate.Triggers>
<Trigger SourceName="ShowCheck"
Property="IsChecked"
Value="True">
<Setter TargetName="ShowCheck"
Property="Foreground"
Value="#777777" />
</Trigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=IsMouseOver,
ElementName=OutterBorder}"
Value="False"/>
<Condition Binding="{Binding Path=IsChecked,
ElementName=ShowCheck}"
Value="True"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard TargetName="HighlightBorder">
<ColorAnimation Storyboard.TargetProperty="Color"
To="Black"
Duration="0:0:0.3" />
</Storyboard>
</BeginStoryboard>
<BeginStoryboard>
<Storyboard TargetName="CheckColor">
<ColorAnimation Storyboard.TargetProperty="Color"
To="#777777"
Duration="0:0:0.3"/>
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=IsMouseOver,
ElementName=OutterBorder}"
Value="True"/>
<Condition Binding="{Binding Path=IsChecked,
ElementName=ShowCheck}"
Value="True" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard TargetName="HighlightBorder">
<ColorAnimation Storyboard.TargetProperty="Color"
To="CornflowerBlue"
Duration="0:0:0.3"/>
</Storyboard>
</BeginStoryboard>
<BeginStoryboard>
<Storyboard TargetName="CheckColor">
<ColorAnimation Storyboard.TargetProperty="Color"
To="White"
Duration="0:0:0.3" />
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=IsMouseOver,
ElementName=OutterBorder}"
Value="True"/>
<Condition Binding="{Binding Path=IsChecked,
ElementName=ShowCheck}"
Value="False"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard TargetName="HighlightBorder">
<ColorAnimation Storyboard.TargetProperty="Color"
To="CornflowerBlue"
Duration="0:0:0.3"/>
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
</MultiDataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

Your animation storyboards are stacking up. You need to remove them in the ExitActionsof the triggers. Name your BeginStoryboardinstances and use RemoveStoryboardin the ExitActionsto clear the storyboard and allow another storyboard to work. For example:
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=IsMouseOver,
ElementName=OutterBorder}"
Value="False"/>
<Condition Binding="{Binding Path=IsChecked,
ElementName=ShowCheck}"
Value="True"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<!-- Give BeginStoryboard a name -->
<BeginStoryboard x:Name="MouseNotOverAndChecked">
<Storyboard TargetName="HighlightBorder">
<ColorAnimation Storyboard.TargetProperty="Color"
To="Black"
Duration="0:0:0.3" />
</Storyboard>
</BeginStoryboard>
<BeginStoryboard>
<Storyboard TargetName="CheckColor">
<ColorAnimation Storyboard.TargetProperty="Color"
To="#777777"
Duration="0:0:0.3"/>
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
<!-- Use the exit actions to remove the storyboard. Use the name given above -->
<MultiDataTrigger.ExitActions>
<RemoveStoryboard BeginStoryboardName="MouseNotOverAndChecked" />
</MultiDataTrigger.ExitActions>

Related

Why does my MultiDataTrigger run only once even if it satisfies the conditions?

In an attempt to further reduce my c# code, I've tried handling the Hamburger Menu's animation on XAML. I've applied a MultiDataTrigger with a condition that takes the current Width and the Button press from the Hamburger Menu Button. It animates the first Width 70 -> 150 and Width 150 -> 70 but after that it doesn't work anymore.
<Grid x:Name="NavigationGrid" Grid.RowSpan="2" Background="Black">
<StackPanel Margin="0">
<Button x:Name="HamburgerMenuBtn" Style="{DynamicResource NavigationBtn_Style}"/>
</StackPanel>
<Grid.Style>
<Style TargetType="Grid">
<Setter Property="Width" Value="70"/>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=NavigationGrid,Path=ActualWidth}" Value="70"/>
<Condition Binding="{Binding ElementName=HamburgerMenuBtn,Path=IsPressed}" Value="True"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
From="70"
To="150"
Duration="0:0:0.5"
Storyboard.TargetProperty="Width"/>
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=NavigationGrid,Path=ActualWidth}" Value="150"/>
<Condition Binding="{Binding ElementName=HamburgerMenuBtn,Path=IsPressed}" Value="True"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
From="150"
To="70"
Duration="0:0:0.5"
Storyboard.TargetProperty="Width"/>
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
</Grid>
IsPressed is only true momentarily. Lose that second animation. Just use the first animation but make it reverse. So it grows then reduces the size. AutoReverse="true".
You might also have to increase duration a little.

Prevent TabItem event from triggering WPF

<TabControl x:Name="tabControl" TabStripPlacement="Top" BorderBrush="White" FontSize="14" Grid.ColumnSpan="2" HorizontalAlignment="Left" Height="98" Margin="0,2,0,0" VerticalAlignment="Top" Width="992" FontFamily="Segoe UI">
<TabControl.Resources>
<Style TargetType="TabItem">
<Style.Triggers>
<Trigger Property="TabItem.IsSelected" Value="True">
<Setter Property="TabItem.Foreground" Value="#FF0090D3"/>
<Setter Property="TabItem.FontSize" Value="14"/>
<Setter Property="TabItem.FontFamily" Value="Segoe Ui SemiBold"/>
</Trigger>
</Style.Triggers>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TabItem">
<Border Name="Border" BorderThickness="0,0,0,0" BorderBrush="White" Background="White" CornerRadius="13,13,13,13" Margin="1,0">
<ContentPresenter x:Name="ContentSite"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Header"
Margin="10,2"/>
</Border>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<ParallelTimeline>
<ColorAnimation Storyboard.TargetName="Border" Storyboard.TargetProperty="(Border.Background).Color" From="White" To="LightGray" Duration="0:0:0.2"/>
</ParallelTimeline>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard>
<ParallelTimeline>
<ColorAnimation Storyboard.TargetName="Border" Storyboard.TargetProperty="(Border.Background).Color" From="LightGray" To="White" Duration="0:0:0.2"/>
</ParallelTimeline>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.Resources>
<TabItem Width="190" Visibility="Hidden" />
<TabItem Height="25" IsSelected="True" Width="63" Header="Home">
<Canvas>
<Rectangle x:name="rect1" Fill="#FFF4F4F5" Height="59" Width="58" Canvas.Top="3" Canvas.Left="1">
<Rectangle.Style>
<Style TargetType="Rectangle">
<Style.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="Fill.Color" To="LightGray" Duration="0:0:0.2"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="Fill.Color" To="White" Duration="0:0:0.2"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
</Canvas>
</TabItem>
<TabItem Width="63" Header="Tools"/>
<TabItem Width="76" Header="Add-ons" />
</TabControl>
The code allows me to change the tab header color when the mouse is over the header.However,the problem is....when mouse is over a content inside a tabitem,the MouseEnter event of both the TabItem and the content fires.Which results in : If i hover over a content(eg. a rectangle that i'm using),the MouseEnter event of the content/control is fired.But it also fires the 'MouseEnter' event of the tabItem...So the tabItem/TabHeader chages it's color even when i don't hover over the header/TabItem rather when i hover over a control/content inside the tabitem...How do i prevent this ?
Update
I found this code :
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="true" />
<Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="false"/>
<Condition Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}" Value="Top"/>
from here.But where should i put it ?
Damn!! It was reallllyyy easy! Just changed :
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
To :
<ControlTemplate.Triggers>
<EventTrigger SourceName="ContentSite" RoutedEvent="MouseEnter">

datatrigger cannot set bound property

I have 2 checkboxes (chkMfsUi and chkMfs). When I check chkMfsUi, I also want to check chkMfs (and disable it).
I tried it with a datatrigger:
<Style x:Key="MfsCheckBoxStyle" TargetType="CheckBox">
<Setter Property="IsEnabled" Value="True" />
<Setter Property="IsChecked" Value="False" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, ElementName=chkMfsUi}" Value="True">
<Setter Property="IsEnabled" Value="False" />
<Setter Property="IsChecked" Value="True" />
</DataTrigger>
</Style.Triggers>
</Style>
And these are my checkboxes:
<StackPanel>
<CheckBox Name="chkMfsUi"
Checked="CheckBox_Checked"
Content="MFS - UI"
IsChecked="{Binding MfsUi}"
Unchecked="CheckBox_Checked" />
<CheckBox Content="MFS" IsChecked="{Binding Mfs}" Style="{StaticResource MfsCheckBoxStyle}" />
</StackPanel>
The IsEnabled property work fine, but the IsChecked doesn't. Maybe because it is bound? I am also using INotifyPropertyChanged with these properties.
If I set it in code behind, it works, but is it possible with a trigger though?
Regards,
Alfons
EDIT:
As appeared from the current answers, my question seems to be incomplete. I need to have the following three states:
AND last but not least: Both checkboxes' IsChecked properties must be bound! (This is the moment when the trouble comes in)
Try this
<StackPanel Grid.Column="1">
<CheckBox x:Name="chkMfsUi" IsChecked="True"></CheckBox>
<CheckBox x:Name="chkMfs" IsChecked="{Binding ElementName=chkMfsUi,Path=IsChecked}">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="IsEnabled" Value="False"/>
</Trigger>
</Style.Triggers>
</Style>
</CheckBox.Style>
</CheckBox>
Another Method : By using style in resource
Add this namespace first xmlns:Globalvaribale="clr-namespace:System;assembly=mscorlib"
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Globalvaribale="clr-namespace:System;assembly=mscorlib">
<Window.Resources>
<Globalvaribale:String x:Key="chkMfsUi">chkMfsUi</Globalvaribale:String>
<Style x:Key="chkMfsstyle" TargetType="CheckBox">
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked,ElementName={StaticResource chkMfsUi}}" Value="True">
<Setter Property="IsEnabled" Value="False"/>
<Setter Property="IsChecked" Value="True"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<StackPanel Grid.Column="1">
<CheckBox x:Name="chkMfsUi"></CheckBox>
<CheckBox Style="{StaticResource chkMfsstyle}"/>
</StackPanel>
Output
In this case you can use the EventTrigger:
Represents a trigger that applies a set of actions in response to an event.
Example:
<StackPanel>
<StackPanel.Triggers>
<EventTrigger RoutedEvent="CheckBox.Checked" SourceName="First">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetName="Second"
Storyboard.TargetProperty="IsChecked">
<DiscreteBooleanKeyFrame KeyTime="00:00:00" Value="True" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="CheckBox.Checked" SourceName="Second">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetName="First"
Storyboard.TargetProperty="IsChecked">
<DiscreteBooleanKeyFrame KeyTime="00:00:00" Value="True" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="CheckBox.Unchecked" SourceName="First">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetName="Second"
Storyboard.TargetProperty="IsChecked">
<DiscreteBooleanKeyFrame KeyTime="00:00:00" Value="False" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="CheckBox.Unchecked" SourceName="Second">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetName="First"
Storyboard.TargetProperty="IsChecked">
<DiscreteBooleanKeyFrame KeyTime="00:00:00" Value="False" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</StackPanel.Triggers>
<CheckBox Name="First"
Content="First" />
<CheckBox Name="Second"
Content="Second" />
</StackPanel>
The Storyboard can be stored in Resources for readability, like so:
<Window.Resources>
<Storyboard x:Key="FirstCheckedStory" ... />
</Window.Resources>
And then use like this:
<EventTrigger RoutedEvent="CheckBox.Checked" SourceName="First">
<BeginStoryboard Storyboard="{StaticResource FirstCheckedStory}" />
</EventTrigger>
Also, the Storyboard can contain several actions, just put him in order:
<Storyboard>
<BooleanAnimationUsingKeyFrames ... />
<BooleanAnimationUsingKeyFrames ... />
</Storyboard>

ListBoxItem ControlTemplete.Triggers WPF

I am applying a ItemContainerStyle to a ListBox control. In my ListBoxItem style I have several triggers containing storyboard animations that apply to the current state of the ListBoxItem (IsSelected, IsMouseOver).
It all works fine and dandy until after I have selected a ListBoxItem, then the IsMouseOver storyboard animation isn't fired for the ListBoxItem which was previously selected.
I can't see where the problem is, so I am hoping someone will help me out with this issue.
Cheers
Here is the code I am using
<Style x:Key="ListBoxFeedItemStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="Padding" Value="2,0,0,0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border x:Name="Bd" Background="{TemplateBinding Background}" Margin="5" SnapsToDevicePixels="true">
<Grid Name="Grid" Height="Auto" Margin="5">
<TextBlock Margin="10" Text="{Binding Path=Name}" FontSize="14" TextTrimming="CharacterEllipsis" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="0:0:0.1" Storyboard.TargetName="Bd" Storyboard.TargetProperty="Background.Color" To="#4CDFDFDF" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="0:0:0.1" Storyboard.TargetName="Bd" Storyboard.TargetProperty="Background.Color" To="#00DFDFDF" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsSelected" Value="true">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="0:0:0.1" Storyboard.TargetName="Bd" Storyboard.TargetProperty="Background.Color" To="#FFDFDFDF" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="0:0:0.1" Storyboard.TargetName="Bd" Storyboard.TargetProperty="Background.Color" To="#00DFDFDF" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Check the order of your Triggers.
Have a look at Multiple storyboards on one property
Check out Yuri's answer.May be that's what you are looking for.

ListBox expand selected item

I have the following code snippet (copy and paste into kaxaml, xamlpad, etc to try it)
that collapses all but the selected item. However, I want to revert back to all visible
when the mouse is not over the ListBox and I just cannot get it to work short of going code behind. I am using the IsMouseOver ListBox property to set selected item properties on the ListBox to attempt to trigger an update but no luck.
Any ideas?
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<ListBox
Name="lb"
Width="100"
Height="100"
Background="Red"
SelectionMode="Single">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="1"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBoxItem Background="AliceBlue">Item 1
</ListBoxItem>
<ListBoxItem Background="Aquamarine">Item
</ListBoxItem>
<ListBoxItem Background="Azure">Item
</ListBoxItem>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Visibility" Value="Visible"/>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelected}" Value="False"/>
<Condition Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBox}},Path=SelectedItems.Count}" Value="1"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard Duration="0:0:1">
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:1" Value="{x:Static Visibility.Collapsed}"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation Duration="0:0:1" Storyboard.TargetProperty="Opacity" To="0"/>
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelected}" Value="True"/>
<Condition Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBox}},Path=SelectedItems.Count}" Value="1"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard Duration="0:0:0">
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation Duration="0:0:0" Storyboard.TargetProperty="Opacity" To="1"/>
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.Style>
<Style>
<Style.Triggers>
<Trigger Property="ListBox.IsMouseOver" Value="False">
<Setter Property="ListBox.SelectedItem" Value="{x:Null}"/>
<Setter Property="ListBoxItem.IsSelected" Value="False"/>
<Setter Property="ListBox.SelectedIndex" Value="-1"/>
</Trigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave">
<BeginStoryboard>
<Storyboard>
<Int32Animation Duration="0:0:0" Storyboard.TargetProperty="SelectedIndex" To="-1"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</ListBox.Style>
</ListBox>
</Grid>
</Page>
Move your style to resources and apply it when the mouse is over the ListBox.`
<Page.Resources>
<Style x:Key="CustomStyle" TargetType="{x:Type ListBoxItem}">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelected}" Value="False"/>
<Condition Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBox}},Path=SelectedItems.Count}" Value="1"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard Duration="0:0:1">
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:1" Value="{x:Static Visibility.Collapsed}"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation Duration="0:0:1" Storyboard.TargetProperty="Opacity" To="0"/>
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.EnterActions>
<MultiDataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard Duration="0:0:0">
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation Duration="0:0:0" Storyboard.TargetProperty="Opacity" To="1"/>
</Storyboard>
</BeginStoryboard>
</MultiDataTrigger.ExitActions>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Page.Resources>
<Grid>
<ListBox
Name="lb"
Width="100"
Height="100"
Background="Red"
SelectionMode="Single">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="1"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBoxItem Background="AliceBlue">Item 1
</ListBoxItem>
<ListBoxItem Background="Aquamarine">Item
</ListBoxItem>
<ListBoxItem Background="Azure">Item
</ListBoxItem>
<ListBox.Style>
<Style>
<Style.Triggers>
<Trigger Property="ListBox.IsMouseOver" Value="True">
<Setter
Property="ListBox.ItemContainerStyle"
Value="{StaticResource CustomStyle}"/>
</Trigger>
</Style.Triggers>
</Style>
</ListBox.Style>
</ListBox>
</Grid>
`
Also note the usage of the MultiDataTrigger.ExitActions, these are the actions to apply when the trigger object becomes inactive.

Resources