WPF鼠标拖拽的最佳实现

ops/2024/10/21 6:46:19/

WPF鼠标拖拽的最佳实现

在很多项目中都会遇到鼠标拖拽控件移动的需求,常见的有从在列表中拖拽列表项移动,拖拽控件移动等。

本文将介绍2种拖拽的简单的实现

列表项的拖拽

本文将使用 gong-wpf-dragdrop 这个github上的库来实现列表的拖拽的效果,项目地址
优点非常简单,几行代码就可以实现效果了。

1.先看最终效果

在这里插入图片描述

2.实现过程

  1. 在Neget中搜索并安装gong-wpf-dragdrop库

    在这里插入图片描述

  2. 在需要拖拽的列表控件上添加代码

            <ListBoxx:Name="MyListBox"dd:DragDrop.DropHandler="{Binding}"dd:DragDrop.DropTargetAdornerBrush="{DynamicResource PrimaryThemeColor}"dd:DragDrop.IsDragSource="True"dd:DragDrop.IsDropTarget="True"dd:DragDrop.UseDefaultDragAdorner="True"ItemsSource="{Binding PipeList}"SelectionChanged="ListBox_SelectionChanged"><ListBox.ItemTemplate><DataTemplate><Border Height="40"><Grid Background="Transparent"><TextBlock VerticalAlignment="Center" Text="{Binding}" /></Grid></Border></DataTemplate></ListBox.ItemTemplate></ListBox>
    

    并且引入命名空间

    xmlns:dd="urn:gong-wpf-dragdrop"
    

    此时就能看到列表已经可以被拖拽排序了

    在这里插入图片描述

    此时会有一点小瑕疵,那就是预览项并不会出现在鼠标点下的位置,而是在光标的上边,这时需要通过 DragAdornerTranslation 属性来控制偏移,实现一个更好的拾起效果,在列表中添加事件SelectionChanged 代码如下:

            private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e){// 获取当前选中项的ListBoxItemListBoxItem selectedItem = (ListBoxItem)MyListBox.ItemContainerGenerator.ContainerFromItem(MyListBox.SelectedItem);if (selectedItem != null){// 获取鼠标相对于当前选中项的位置Point position = Mouse.GetPosition(selectedItem);// 偏移鼠标相对于当前选中项的位置GongSolutions.Wpf.DragDrop.DragDrop.SetDragAdornerTranslation(MyListBox, new Point(-position.X, position.Y));//= "10,10"}}
    

    最终就实现了我们需要的效果

    在这里插入图片描述

控件的拖拽

控件的拖拽移动比较简单,就是直接使用代码实现了,主要会用到鼠标的三个事件

  • PreviewMouseDown 鼠标按下
  • PreviewMouseMove 鼠标移动
  • PreviewMouseUp 鼠标抬起

先看效果

在这里插入图片描述

实现过程

通过TranslateTransform来实现更改控件的位置,通过鼠标按下事件中,记录的按下时的鼠标坐标,和控件当前坐标,通过鼠标 移动事件中,鼠标位置偏移量,还原到控件上,就实现了这个效果,代码如下

xaml文件代码:

          <ButtonWidth="120"Height="40"Content="Test"PreviewMouseDown="Button_PreviewMouseDown"PreviewMouseMove="Button_PreviewMouseMove"PreviewMouseUp="Button_PreviewMouseUp" />

cs代码:

public bool isMouseDown = false;
public Point mouseDownPosition;
public Point mouseDownControlPosition;
private void Button_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{isMouseDown = true;var ctl = sender as UIElement;mouseDownPosition = e.GetPosition(null);var transform = ctl.RenderTransform as TranslateTransform;if (transform == null){transform = new TranslateTransform();ctl.RenderTransform = transform;}mouseDownControlPosition = new Point(transform.X, transform.Y);ctl.CaptureMouse();
}private void Button_PreviewMouseMove(object sender, MouseEventArgs e)
{if (isMouseDown){var button = (UIElement)sender;TranslateTransform transform = button.RenderTransform as TranslateTransform;Point currentPoint = e.GetPosition(null);double offsetX = currentPoint.X - mouseDownPosition.X;double offsetY = currentPoint.Y - mouseDownPosition.Y;double newX = mouseDownControlPosition.X + offsetX;double newY = mouseDownControlPosition.Y + offsetY;transform.X = newX;transform.Y = newY;}
}private void Button_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{var ctl = sender as UIElement;isMouseDown = false;ctl.ReleaseMouseCapture();
}

这样就实现了控件移动的效果

在这里插入图片描述


http://www.ppmy.cn/ops/28741.html

相关文章

【并行计算】【《并行程序设计导论》笔记】第三章:用MPI进行分布式内存编程

文章目录 3.1|预备知识编译与执行打印来自进程问候语句的MPI程序编译执行 通信子SPMD程序MPI_Send()方法status_p参数MPI_Send()和MPI_Recv()的语义潜在的陷阱 个人主页&#xff1a;丷从心 系列专栏&#xff1a;并行计算 3.1|预备知识 编译与执行 打印来自进程问候语句的MPI…

【Mac】Mac安装软件常见问题解决办法

前言 刚开始用Mac系统的小伙伴或者在更新系统版本后运行App的朋友会经常碰到弹窗提示「xxx已损坏&#xff0c;无法打开&#xff0c;您应该将它移到废纸篓」、「打不开xxx&#xff0c;因为Apple无法检查其是否包含恶意软件」、「打不开xxx&#xff0c;因为它来自身份不明的开发…

Elasticsearch 索引 blocks:深入探讨数据保护

Elasticsearch 作为搜索和分析数据的首选分布式引擎在技术领域脱颖而出&#xff0c;尤其是在处理日志、事件和综合文本搜索时。 它的与众不同之处在于它如何让你使用各种块选项调整对其索引的访问。 这对于那些负责技术项目的人&#xff08;比如管理员和编码员&#xff09;来说…

特别的时钟特别的倒计时

念念不忘的歌曲&#xff1a;Thats Why You Go Away <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title&…

数据结构的队列(c语言版)

一.队列的概念 1.队列的定义 队列是一种常见的数据结构&#xff0c;它遵循先进先出的原则。类似于现实生活中排队的场景&#xff0c;最先进入队列的元素首先被处理&#xff0c;而最后进入队列的元素则要等到前面的元素都被处理完后才能被处理。 在队列中&#xff0c;元素只能…

中间件解析漏洞

1 、 apache 解析漏洞 漏洞环境搭建 下载 vulhub git clone https://github.com/vulhub/vulhub.git 进入对应漏洞目录、 cd vulhub/httpd/apache_parsing_vulnerability apt-get docker-compose 启动漏洞环境 docker-compose up -d 注&#xff1a;启动容器时&#xf…

微信小程序与web-view网页进行通信的尝试

首先&#xff0c;微信小程序向web-view传递数据一般通过地址栏传参的形式&#xff08;给src赋值或者修改hash&#xff09;&#xff0c;这样一般就已经能够满足实际开发需求了&#xff0c;所以这里主要探讨web-view向微信小程序传参。下面&#xff0c;我们从官方文档入手&#x…

2024年第二十六届“华东杯”(B题)大学生数学建模挑战赛|数学建模完整代码+建模过程全解全析

当大家面临着复杂的数学建模问题时&#xff0c;你是否曾经感到茫然无措&#xff1f;作为2022年美国大学生数学建模比赛的O奖得主&#xff0c;我为大家提供了一套优秀的解题思路&#xff0c;让你轻松应对各种难题。 让我们来看看华东杯 (B题&#xff09;&#xff01; 第一个问题…