WPF手柄拖放以及左键单击

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WPF手柄拖放以及左键单击相关的知识,希望对你有一定的参考价值。

我在使DragDrop.DoDragDrop与左键单击事件配合使用方面遇到一些麻烦。

我的控件有几个链接,可以拖动它们或单击鼠标左键进行访问。

我目前订阅预览鼠标移动事件,如果按下鼠标左键,我将在其中启动拖放事件。

[在另一个回叫中,我处理鼠标左键的上下移动事件以检查是否单击。无论如何,是否要检查DragDrop是否确实发生了拖放事件?

答案

请参见this link drag drop in wpf explained end to end,然后向下滚动至“检测拖放”部分

在此处插入代码以防止博客丢失...

从[http://msdn2.microsoft.com/en-us/library/aa289508(vs.71).aspx]开始,这是典型的拖放操作中的事件顺序:

通过调用源控件的DoDragDrop方法来启动拖动。

DoDragDrop方法采用两个参数:数据,指定要允许通过的数据效果,指定允许进行哪些操作(复制和/或移动)

将自动创建一个新的DataObject对象。这反过来引发GiveFeedback事件。在大多数情况下,您无需担心GiveFeedback事件,但是如果您希望在拖动过程中显示自定义鼠标指针,则可以在其中添加代码。

任何将AllowDrop属性设置为True的控件都是潜在的放置目标。可以在设计时在“属性”窗口中设置AllowDrop属性,也可以在Form_Load事件中以编程方式设置。

当鼠标移过每个控件时,将引发该控件的DragEnter事件。 GetDataPresent方法用于确保数据格式适合于目标控件,并且Effect属性用于显示适当的鼠标指针。]

如果用户在有效的放置目标上释放鼠标按钮,则会引发DragDrop事件。 DragDrop事件处理程序中的代码从DataObject对象提取数据,并将其显示在目标控件中。

检测拖放

在调用DoDragDrop之前,我们必须在源上检测到鼠标的拖动操作。鼠标的拖动通常是MouseLeftButtonDown + MouseMove(在MouseLeftButton上升之前)。

因此,我们的拖放源控件需要预订以下两个事件:

void Window1_Loaded(object sender, RoutedEventArgs e)

    this.DragSource.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(DragSource_PreviewMouseLeftButtonDown);
    this.DragSource.PreviewMouseMove += new MouseEventHandler(DragSource_PreviewMouseMove);

为了防止在用户意外拖动时启动错误的拖放操作,可以使用

SystemParameters.MinimumHorizo​​ntalDragDistance和SystemParameters.MinimumVerticalDragDistance

一种方法是在MouseLeftButtonDown上,记录起始位置,然后onMouseMove检查鼠标是否移动了足够的距离。。

void DragSource_PreviewMouseMove(object sender, MouseEventArgs e)

    if (e.LeftButton == MouseButtonState.Pressed && !IsDragging)
    
        Point position = e.GetPosition(null);

        if (Math.Abs(position.X - _startPoint.X) > SystemParameters.MinimumHorizontalDragDistance ||
                Math.Abs(position.Y - _startPoint.Y) > SystemParameters.MinimumVerticalDragDistance)
        
            StartDrag(e); 

        
       


void DragSource_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)

    _startPoint = e.GetPosition(null);

它是阻力..现在是什么?

数据!您需要找出拖动时鼠标下方的内容。我将省略简单的方法,并假设谁触发了MouseMove就是我要拖动的对象..因此,请查看MouseEventArgs.OriginalSource .. [或者您可以使用VisualTreeHelper进行一些2D HitTesting ..在本文的第3部分中将尝试引导您完成对列表框的命中测试-这是我遇到的另一种常见情况-。

一旦有了要拖动的对象,就需要将发送的内容打包到描述要传递的数据的DataObject中。DataObject是一个包装器,用于将通用数据(以可扩展格式标识)推入/拖放。只要源和目标都理解该格式,就可以进行设置。因此,DataObject有几个有趣的方法:

SetData(类型格式,对象数据)///格式是您可以传递任何自定义类型的当天传递的“格式”(例如Formats.Text,Formats.Image等。)

GetDataPresent(Type format)///是放置目标用来查询和提取数据的对象。如果它是可以处理的类型,它将调用GetData()并处理它..

[这里没有太多有趣的东西。在示例中,我只是将数据硬编码为字符串类型...这使得粘贴到外部容器(例如Word,可以用来测试该部分的内容)更容易文字)。我必须强调,拖放应该与数据有关...在拖放操作期间提供视觉反馈。.

在调用DoDragDrop()之前,我们有一些“选择”可以围绕我们要提供的反馈以及d&d的“范围”做出选择。

我们是否希望在执行拖动操作时显示自定义光标?如果我们想要一个游标,应该是什么?

我们想拖多远?在应用程序内还是跨Windows应用程序?

最简单的情况:没有自定义光标,我们希望它在应用程序之间拖动:

如果您不想花哨的光标,就完成了!!您可以直接调用DoDragDrop ...

private void StartDrag(MouseEventArgs e)

    IsDragging = true;
    DataObject data = new DataObject(System.Windows.DataFormats.Text.ToString(), "abcd");
    DragDropEffects de = DragDrop.DoDragDrop(this.DragSource, data, DragDropEffects.Move);
    IsDragging = false;

注意:此代码允许您跨进程拖放,它使用默认的操作系统反馈(例如+用于复制)。

存在拖放/输入/保留附件事件您可以在拖动的UIElement上为这些(或一个)事件订阅方法,并查看是否发生了拖动。

另一答案

存在拖放/输入/保留附件事件您可以在拖动的UIElement上为这些(或一个)事件订阅方法,并查看是否发生了拖动。

另一答案

由于我无法评论已接受的答案(到目前为止信誉分数太低,并且提供的链接不再有效,我想在此处发布新链接:

Drag&Drop in Wpf explained end to end

以上是关于WPF手柄拖放以及左键单击的主要内容,如果未能解决你的问题,请参考以下文章

带手柄的拖放

DataGridView多行选择清除鼠标左键拖放

WPF 左键单击弹出菜单 ContextMenu

java工作复习——鼠标事件——action类——单击鼠标左键不释放以及释放的操作

未左键单击 Interaction.Triggers 按钮时 WPF 应用程序崩溃

java+selenium+new——模拟——单击鼠标左键不释放以及释放的操作——action类