wpf - 发生拖动操作时,如何在 XAML 中激活 WPF 触发器?

标签 wpf triggers drag-and-drop

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

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

那么有没有一种简单的方法可以说“嘿......我正在进行拖放操作,所以激活这个触发器”还是我在这里不走运?

更新

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

最佳答案

我刚刚遇到了这个问题,我的解决方案包括使用一个附加属性来提供缺失的 IsDragging :

  • 定义附加属性
    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);
    }
    
  • 创建此扩展方法以帮助您设置属性
    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);
        }
    }
    
  • 根据所使用的控件(例如 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);
        }
    }
    
  • 在触发器中使用属性
    <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>
    
  • 关于wpf - 发生拖动操作时,如何在 XAML 中激活 WPF 触发器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4421247/

    相关文章:

    c# - 在标题中使用 '/' 时如何防止列不显示在 WPF 数据网格中?

    wpf - 找不到 ViewModel 的 View

    mysql - Mysql 中的触发器(之后/之前)

    javascript - VueJS 监听自定义事件?

    java - 带有视觉指示的拖放

    .net - WPF 图像/渲染事件

    c# - 如何计算立方体中的点是否在WPF 3D中可见

    Oracle 触发器 UPDATE 而不是 INSERT

    web-services - SQL 触发器可以调用 Web 服务吗?

    javascript - 如何允许用户单击可放置的 div,以便在单击可放置的 div 后禁用另一个 div 的放置功能