当拖动操作发生时,我们如何在XAML中激活WPF触发器?

时间:2010-12-12 10:37:50

标签: wpf triggers drag-and-drop

我们正在寻找一种方法来在XAML中建立WPF触发器,看看我们是否处于拖放操作中。根据我们是否存在,我们需要不同的悬停行为,这就是为什么需要它。

我能想到的唯一方法是处理拖动开始和结束事件并手动跟踪状态,但这需要代码隐藏,而不是纯XAML。此外,它似乎完全矫枉过正,特别是因为我们必须在每个潜在的跌落目标上做到这一点,这真是一种痛苦。

有没有一种简单的方法可以说'嘿......我正在进行拖放操作,所以让这个触发器处于活动状态'或者我运气不好吗?


更新

为了阐明我们正在尝试做什么,目前在纯XAML中,您可以创建一个样式,然后设置一个样式触发器来检查IsMouseOver属性,然后绘制一个背景突出显示。好吧,我们想要这样做,但我们想说'IsMouseOver'是否为真如果IsDragging = true则应用此触发器。

3 个答案:

答案 0 :(得分:2)

我刚遇到这个问题,我的解决方案是使用附加属性来提供丢失的IsDragging

  1. 定义附加属性

    public static readonly DependencyProperty IsDraggingProperty =
        DependencyProperty.RegisterAttached
        (
            "IsDragging",
            typeof(bool),
            typeof(ClassContainingThisProperty),
            new UIPropertyMetadata(false)
        );
    
    public static bool GetIsDragging(DependencyObject source)
    {
        return (bool)source.GetValue(IsDraggingProperty);
    }
    
    public static void SetIsDragging(DependencyObject target, bool value)
    {
        target.SetValue(IsDraggingProperty, value);
    }
    
  2. 创建此扩展方法以帮助您设置属性

    public static TParent FindParent<TParent>(this DependencyObject child) where TParent : DependencyObject
    {
        DependencyObject current = child;
        while(current != null && !(current is TParent))
        {
            current = VisualTreeHelper.GetParent(current);
        }
        return current as TParent;
    }
    
    public static void SetParentValue<TParent>(this DependencyObject child, DependencyProperty property, object value) where TParent : DependencyObject
    {
        TParent parent = child.FindParent<TParent>();
        if(parent != null)
        {
            parent.SetValue(property, value);
        }
    }
    
  3. 根据所使用的控件(例如ListView)处理DragDrop事件,以设置元素的附加属性。

    private void OnDragEnter(object sender, DragEventArgs e)
    {
        DependencyObject source = e.OriginalSource as DependencyObject;
        if (source != null)
        {
            source.SetParentValue<ListViewItem>(ClassContainingTheProperty.IsDraggingProperty, true);
        }
    }
    
    private void OnDragLeave(object sender, DragEventArgs e)
    {
        DependencyObject source = e.OriginalSource as DependencyObject;
        if(source != null)
        {
            source.SetParentValue<ListViewItem>(ClassContainingTheProperty.IsDraggingProperty, false);
        }
    }
    
    private void OnDrop(object sender, DragEventArgs e)
    {
        DependencyObject source = e.OriginalSource as DependencyObject;
        if(source != null)
        {
            source.SetParentValue<ListViewItem>(ClassContainingTheProperty.IsDraggingProperty, false);
        }
    }
    
  4. 在触发器中使用属性

    <ControlTemplate TargetType="{x:Type ListViewItem}">
      <ControlTemplate.Triggers>
        <Trigger Property="namespace:ClassContainingTheProperty.IsDragging" Value="True">
          <Setter Property="Background" Value="White" />
          <Setter Property="BorderBrush" Value="Black" />
        </Trigger>
      </ControlTemplate.Triggers>
    </ControlTemplate>
    

答案 1 :(得分:0)

我只见过用事件处理程序实现的拖放操作,所以我觉得你运气不好。我建议您创建自己的依赖项属性以指示正在进行的拖放。

答案 2 :(得分:0)

如果它是真正的DragDrop事件,只需注意DragOver事件......

            <EventTrigger RoutedEvent="DragOver">
                <BeginStoryboard>
                    <Storyboard Storyboard.TargetProperty="Fill.Color">
                        <ColorAnimation From="White" To="Black" Duration="0:0:1" />
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>