gpt4 book ai didi

c# - WPF 处理拖放和左键单击

转载 作者:太空狗 更新时间:2023-10-30 00:05:22 25 4
gpt4 key购买 nike

我在使 DragDrop.DoDragDrop 与左键单击事件配合良好时遇到了一些麻烦。

我的控件有几个链接,可以四处拖动或左键单击访问。

我目前订阅了预览鼠标移动事件,这是我在按下鼠标左键时启动拖放事件的地方。

在另一个回调中,我处理鼠标左键按下和向上事件以检查是否单击。有没有办法检查 DragDrop 是否确实发生了拖放事件?

最佳答案

参见 this link drag drop in wpf explained end to end向下滚动到“检测拖放”部分

此处插入的代码包含博客丢失...

来自 [ http://msdn2.microsoft.com/en-us/library/aa289508(vs.71).aspx]以下是典型拖放操作中的事件序列:

Dragging is initiated by calling the DoDragDrop method for the source control.

The DoDragDrop method takes two parameters: data, specifying the data to pass allowedEffects, specifying which operations (copying and/or moving) are allowed

A new DataObject object is automatically created. This in turn raises the GiveFeedback event. In most cases you do not need to worry about the GiveFeedback event, but if you wanted to display a custom mouse pointer during the drag, this is where you would add your code.

Any control with its AllowDrop property set to True is a potential drop target. The AllowDrop property can be set in the Properties window at design time, or programmatically in the Form_Load event.

As the mouse passes over each control, the DragEnter event for that control is raised. The GetDataPresent method is used to make sure that the format of the data is appropriate to the target control, and the Effect property is used to display the appropriate mouse pointer.

If the user releases the mouse button over a valid drop target, the DragDrop event is raised. Code in the DragDrop event handler extracts the data from the DataObject object and displays it in the target control.

检测拖放

在调用 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.MinimumHorizontalDragDistance and 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 部分中将尝试引导您完成列表框的 HitTest ——这是我遇到的另一种常见情况。

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

SetData ( Type format, object data ) /// format is the "format" of the day you are passing ( e.g. Formats.Text, Formats.Image, etc.. ) you can pass any custom types.

GetDataPresent ( Type format ) /// is what the drop target will use to inquire and extract the data .. if it is a type it can handle, it will call GetData () and handle it ..

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

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

Do we want a custom cursor to display while we are doing the Drag operation ? If we want a cursor, what should it be?

How far do we want to drag? within the app or across windows apps?

最简单的场景:没有自定义光标,我们希望它可以跨应用拖动:

如果你不想要花哨的光标,你就完成了!!可以直接调用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;
}

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

关于c# - WPF 处理拖放和左键单击,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12802122/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com