c# wpf 实现窗口任意区域点击拖动

您所在的位置:网站首页 鼠标拖拽窗口 c# wpf 实现窗口任意区域点击拖动

c# wpf 实现窗口任意区域点击拖动

2023-07-25 00:45| 来源: 网络整理| 查看: 265

系列文章目录

第一章 Grid内控件拖动 第二章 Canvas内控件拖动 第三章 任意控件拖动 第四章 窗口拖动(本章) 第五章 附加属性实现任意拖动

文章目录 系列文章目录前言一、简单拖动二、事件冲突问题三、解决方法四、效果预览五、使用示例1、白板的工具条(1)、MainWindow.xaml(2)、MainWindow.xaml.cs(3)、效果预览 总结

前言

点击窗口任意区域可移动功能,在一些业务场景中会使用到,比如工具条或者球形状的窗口等。在wpf要实现此功能简单形式还是比较容易的,但是有一些细节需要专门处理,比如与按钮的点击事件冲突问题,解决事件冲突问题后拖动的灵敏度,可复用性等。

一、简单拖动

基础的拖动功能直接使用Window类的DragMove即可实现: 在Window的PreviewMouseLeftButtonDown中调用DragMove即可。 示例如下:

void Window_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) { DragMove(); }

注:本文实现的是窗口任意区域拖动(比如按钮占满整个窗口),不适用于一般窗口拖动,一般窗口拖动请使用MouseLeftButtonDown事件

二、事件冲突问题

根据上述方法实现窗口拖动后发现出现了事件冲突,即窗口内的控件无法相应鼠标点击事件了。因为DragMove的内部实现使用了SC_MOVE,使标题栏(win32窗口)捕获鼠标,原本窗口失去鼠标捕获。窗口内的控件无法响应鼠标消息,因此上述简单拖动在有控件的窗口中是不可行的(局部拖动是可行的,但本文讲的是任意区域拖动)。 在这里插入图片描述

三、解决方法

解决方法是不在鼠标按下事件中触发拖动,而是在鼠标移动后触发拖动操作。具体步骤如下: 1、注册3个事件如下:

2、定义2个变量记录信息。

Point _pressedPosition ; bool _isDragMoved = false;

3.记录鼠标按下位置

void Window_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) { _pressedPosition = e.GetPosition(this); }

4.鼠标移动触发拖动

void Window_PreviewMouseMove(object sender, System.Windows.Input.MouseEventArgs e) { if (Mouse.LeftButton==MouseButtonState.Pressed && _pressedPosition != e.GetPosition(this)) { _isDragMoved = true; DragMove(); } }

5.鼠标弹起屏蔽消息

void Window_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) { if (_isDragMoved) { _isDragMoved = false; e.Handled = true; } } 四、效果预览

在这里插入图片描述

五、使用示例

由于评论区反馈上述方法存在bug,但是无奈笔者始终没有重现,怀疑是使用方法不正确,或者对本博文讲述功能理解上的差异导致的,在此根据上述方法原封不动的编写如下使用示例,以说明使用场景以及使用方法。

1、白板的工具条 (1)、MainWindow.xaml (2)、MainWindow.xaml.cs using System.Windows; using System.Windows.Input; namespace WpfApp3 { /// /// MainWindow.xaml 的交互逻辑 /// public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } Point _pressedPosition; bool _isDragMoved = false; void Window_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) { _pressedPosition = e.GetPosition(this); } void Window_PreviewMouseMove(object sender, System.Windows.Input.MouseEventArgs e) { if (Mouse.LeftButton == MouseButtonState.Pressed && _pressedPosition != e.GetPosition(this)) { _isDragMoved = true; DragMove(); } } void Window_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) { if (_isDragMoved) { _isDragMoved = false; e.Handled = true; } } private void btn_upload_Click(object sender, RoutedEventArgs e) { MessageBox.Show("上传成功"); } private void btn_close_Click(object sender, RoutedEventArgs e) { Close(); } } } (3)、效果预览

在这里插入图片描述

总结

本文介绍了在窗口任意区域点击拖动的方法。简单的拖动是不可行的,往深一步探究,发现了巧妙的解决方法:在鼠标移动时触发拖动。但这也不是一蹴而就的,这是笔者曾经做项目经过了一定的探究最终得以实现,而本文呈现的是优化后的精简版本,易于实现也很好理解,即是所谓的大道至简。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3