简体   繁体   中英

IsMouserOver Interference With IsSelected in WPF

Hey guys I have an issue with triggers for IsMouserOver and IsSelected . My goal is to create an animation that changes the BorderThickness of my ListViewItems in IsMouserOver . Using EnterActions and ExitActions yields the desired result, however, when I try to also take into account the IsSelected property in another trigger, every property but BorderThickness can be set.

When I remove the whole IsMouseOver trigger, BorderThickness will be set in IsSelected and displayed correctly.

<Style TargetType="{x:Type ListViewItem}" x:Key="SubMenuStyles">
    <Setter Property="Height" Value="40"/>
    <Setter Property="Cursor" Value="Hand"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListViewItem}">
                <Border BorderThickness="{TemplateBinding BorderThickness}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            Background="{TemplateBinding Background}">
                    <ContentPresenter HorizontalAlignment="Left" 
                    VerticalAlignment="Center"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">                    
            <Setter Property="BorderBrush" Value="Orange"/>               
            <Trigger.EnterActions>
                <BeginStoryboard>
                    <Storyboard>
                        <ThicknessAnimation 
   Storyboard.TargetProperty="BorderThickness" From="0,0,0,0" To="10,0,0,0" 
    Duration="0:0:0.5"/>
                    </Storyboard>
                </BeginStoryboard>
            </Trigger.EnterActions>
            <Trigger.ExitActions>
                <BeginStoryboard>
                    <Storyboard>
                        <ThicknessAnimation 
  Storyboard.TargetProperty="BorderThickness" From="10,0,0,0"  To="0,0,0,0" 
                     Duration="0:0:0.5"/>
                    </Storyboard>
                </BeginStoryboard>
            </Trigger.ExitActions>

        </Trigger>
        <Trigger Property="ListViewItem.IsSelected" Value="True">
            <Setter Property="Background" Value="#233E4F"/>
            <Setter Property="BorderThickness" Value="50,0,0,0"/>
            <Setter Property="BorderBrush" Value="Orange"/>
        </Trigger>          
   </Style.Triggers>
</Style>

Problem

The behavior you encountered before is shown in the picture below:

在此处输入图片说明

where the problem is that your orange border is being reset every time the mouse is over the selected item.


What I believe you want to achieve is to keep the fixed 50px border on a selected item, like shown below:

在此处输入图片说明


Solution

In order to achieve that, we need to find a way to execute the animation only for items that are not selected (ie where IsSelected="False") . This is where MultiTrigger s come into play.

MultiTrigger s are quite like "normal" Trigger s with the important addition that they fire not when only one condition is fulfilled, but when all conditions are fulfilled .

eg

<MultiTrigger>
    <MultiTrigger.Conditions>
        <Condition Property="IsMouseOver" Value="True" />
        <Condition Property="IsSelected" Value="False" />
        <!-- More conditions, if you want -->
    </MultiTrigger.Conditions>
    <MultiTrigger.Setters>
        <!-- Will only be set when ALL conditions are fulfilled. -->
    </MultiTrigger.Setters>
    <MultiTrigger.EnterActions>
        <!-- Will also only be executed when ALL conditions are fulfilled -->
    </MultiTrigger.ExitActions>
</MultiTrigger> 

Code

So, in your case, adjust your style to look like this:

<Window.Resources>
    <Style x:Key="SubMenuStyles" TargetType="{x:Type ListViewItem}">
        <Setter Property="Height" Value="40" />
        <Setter Property="Cursor" Value="Hand" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListViewItem}">
                    <Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
                        <ContentPresenter HorizontalAlignment="Left" VerticalAlignment="Center" />
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="ListViewItem.IsSelected" Value="True">
                <Setter Property="Background" Value="#233E4F" />
                <Setter Property="Foreground" Value="White" />
                <Setter Property="BorderThickness" Value="50,0,0,0" />
                <Setter Property="BorderBrush" Value="Orange" />
            </Trigger>
            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <Condition Property="IsMouseOver" Value="True" />
                    <Condition Property="IsSelected" Value="False" />
                </MultiTrigger.Conditions>
                <MultiTrigger.Setters>
                    <Setter Property="BorderBrush" Value="Orange" />
                </MultiTrigger.Setters>
                <MultiTrigger.EnterActions>
                    <BeginStoryboard>
                        <Storyboard>
                            <ThicknessAnimation Storyboard.TargetProperty="BorderThickness"
                                                From="0,0,0,0"
                                                To="10,0,0,0"
                                                Duration="0:0:0.5" />
                        </Storyboard>
                    </BeginStoryboard>
                </MultiTrigger.EnterActions>
                <MultiTrigger.ExitActions>
                    <BeginStoryboard>
                        <Storyboard>
                            <ThicknessAnimation Storyboard.TargetProperty="BorderThickness"
                                                From="10,0,0,0"
                                                To="0,0,0,0"
                                                Duration="0:0:0.5" />
                        </Storyboard>
                    </BeginStoryboard>
                </MultiTrigger.ExitActions>
            </MultiTrigger>
        </Style.Triggers>
    </Style>
</Window.Resources>

<Grid>
    <ListView Width="200"
              Height="150"
              Margin="30">
        <ListViewItem Style="{StaticResource SubMenuStyles}">A ListView</ListViewItem>
        <ListViewItem IsSelected="True" Style="{StaticResource SubMenuStyles}">with several</ListViewItem>
        <ListViewItem Style="{StaticResource SubMenuStyles}">items</ListViewItem>
    </ListView>
</Grid>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM