第
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