ListViewItem 中的 EventTriggers 不应由包含的 ItemTemplate 触发

EventTriggers in ListViewItem should not get triggered by contained ItemTemplate

在一个 wpf 应用程序中,我有一个具有拖放功能的 ListView,它将放置的元素插入到它被放置的位置,而不是列表的末尾。那工作正常。我现在想要实现的似乎是简单的部分 :) 我想向用户说明当​​前拖动的元素将被丢弃在列表中的哪个位置。插入新元素的地方应该有一个空隙。

我的方法是更改​​ ListViewItem 在当前 mousePosition 的 Padding。

<ControlTemplate TargetType="ListViewItem">
    <Border x:Name="BorderA">
        <ContentPresenter />
        <Border.Triggers>

            <!--padding for gap when mouse hovers element-->
            <EventTrigger RoutedEvent="DragEnter" SourceName="BorderA">
                <BeginStoryboard>
                    <Storyboard>
                        <ThicknessAnimation
                            Storyboard.TargetProperty="Padding"
                            From="0,0,0,0" To="0,25,0,0" 
                            BeginTime="0:0:0" Duration="0:0:0.5" 
                            AutoReverse="False" />
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>

            <!--back to normal padding-->
            <EventTrigger RoutedEvent="DragLeave" SourceName="BorderA">
                <BeginStoryboard>
                    <Storyboard>
                        <ThicknessAnimation
                            Storyboard.TargetProperty="Padding"
                            From="0,25,0,0" To="0,0,0,0" 
                            BeginTime="0:0:0" Duration="0:0:0.5" 
                            AutoReverse="False" />
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>

        </Border.Triggers>
    </Border>
</ControlTemplate>

我还需要一个 DataTemplate 来正确显示我的列表项。我在这里简化了它,这可能会使它看起来几乎是多余的,但实际上我需要显示一个复杂的 viewModel,这似乎是问题的一部分。

<DataTemplate x:Key="SortableListBoxItemTemplate" DataType="item:SortableListItemViewModel">
    <Border Background="{StaticResource CallToActionBrush}"
            BorderThickness="{StaticResource BorderThickness}"
            BorderBrush="{StaticResource PassiveBorderBrush_Strong}">
    </Border>
</DataTemplate>

这似乎行得通。当我在拖动另一个元素的同时悬停一个元素时,该元素和前一个列表元素之间会出现间隙。但有时当间隙变大时,鼠标位置会在这个间隙内。这会触发 DragLeave 事件,间隙开始缩小,直到 listItem 再次到达鼠标位置,依此类推。这会导致丑陋的闪烁,我不确定如何避免这种情况。只要 DataTemplate 没有背景颜色,一切都很好。但这不是我想要的视觉效果。只有当我的 listviewItem(或 BorderA)触发了 DragEnter 和 DragLeave 事件时,才有办法触发它们吗?还是有其他完整的方法可以达到我想要的效果?

您的问题是否是导致闪烁的意外 DragLeave 事件?

在这种情况下,我想为您的 BorderA 元素设置透明背景可以解决问题。

   <ControlTemplate TargetType="ListViewItem">
       <Border x:Name="BorderA" Background="Transparent">
           <ContentPresenter />
           <Border.Triggers>

透明背景将为您的整个 ListViewItem 启用命中测试,包括您作为占位符创建的填充。

我找到了解决办法。 问题不是 DragLeave 事件,而是当光标进入项目(来自间隙)时的 DragEnter 事件。这会触发动画再次开始,有人愚蠢地告诉这个动画开始 From="0,0,0,0"...我删除了那部分,一切正常。

对我来说还有一个问题。也许在某些情况下,删除 From-part 不是一种选择。有没有办法向事件触发器添加条件。像 Multitrigger 之类的东西?