基本信息
文件名称:C#wpf实现窗口任意区域点击拖动.docx
文件大小:18.51 KB
总页数:10 页
更新时间:2025-05-20
总字数:约8.08千字
文档摘要

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

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

前言

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

一、简单拖动

基础的拖动功能直接使用Window类的DragMove即可实现:

在Window的PreviewMouseLeftButtonDown中调用DragMove即可。

示例如下:

WindowPreviewMouseLeftButtonDown=Window_PreviewMouseLeftButtonDown/

voidWindow_PreviewMouseLeftButtonDown(objectsender,System.Windows.Input.MouseButtonEventArgse)

DragMove();

}

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

二、事件冲突问题

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

三、解决方法

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

1、注册3个事件如下:

WindowPreviewMouseLeftButtonDown=Window_PreviewMouseLeftButtonDown

PreviewMouseMove=Window_PreviewMouseMove

PreviewMouseLeftButtonUp=Window_PreviewMouseLeftButtonUp/

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

Point_pressedPosition;

bool_isDragMoved=false;

3.记录鼠标按下位置

voidWindow_PreviewMouseLeftButtonDown(objectsender,System.Windows.Input.MouseButtonEventArgse)

_pressedPosition=e.GetPosition(this);

}

4.鼠标移动触发拖动

voidWindow_PreviewMouseMove(objectsender,System.Windows.Input.MouseEventArgse)

if(Mouse.LeftButton==MouseButtonState.Pressed_pressedPosition!=e.GetPosition(this))

_isDragMoved=true;

DragMove();

}

5.鼠标弹起屏蔽消息

voidWindow_PreviewMouseLeftButtonUp(objectsender,MouseButtonEventArgse)

if(_isDragMoved)

_isDragMoved=false;

e.Handled=true;

}

四、效果预览

五、使用示例

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

1、白板的工具条

(1)、MainWindow.xaml

Windowx:xmlns=/winfx/2006/xaml/presentation

xmlns:x=/winfx/2006/xaml

xmlns:d=/expression/blend/2008

xmlns:mc=/markup-compatibility/2006

xml