WPF实现鼠标拖动控件并带有中间动效
Posted jeffrey-chou
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WPF实现鼠标拖动控件并带有中间动效相关的知识,希望对你有一定的参考价值。
一. 前提
要实现鼠标对控件的拖拽移动,首先必须知道下面几点:
-
WPF中的鼠标左键按下、鼠标移动事件,有时候通过XAML界面添加的时候并有没有作用;
-
如果在移动时候要持续修改控件的属性,我们通过改变RenderTransform来修改呈现,而不是直接修改控件本身的属性(会卡);
-
通过 VisualBrush 来填充Rectangle,来实现鼠标拖动控件所形成的影子;
-
通过创建一个带有目标依赖属性的Button的子类,来将有关数据放入Button的子类中;
二. 过程
这里以按钮的拖动,分析一下这个过程:
-
首先在点击按钮(鼠标左键按下),我们以按钮为原型创建一个 “影子” ;
-
在鼠标按住左键拖动的时候,实现对这个 “影子” 的拖动跟随效果;
-
最后,在放开鼠标(鼠标左边抬起)时,将原来的按钮的位置直接移动到抬起时的位置并去除跟随的 “影子”;
三. 代码
这边的代码进行了封装,如过要看没有封装的版本请见示例工程(下面可以下载)
- DragButton 类,继承自 Button 类
public class DragButton : Button { public static readonly DependencyProperty IsDragProperty = DependencyProperty.Register("IsDrag", typeof(Boolean), typeof(DragButton)); public static readonly DependencyProperty CurrentPosProperty = DependencyProperty.Register("CurrentPos", typeof(Point), typeof(DragButton)); public static readonly DependencyProperty ClickPosProperty = DependencyProperty.Register("ClickPos", typeof(Point), typeof(DragButton)); /// <summary> /// 是否拖拽 /// </summary> public bool IsDrag { get { return (bool)this.GetValue(IsDragProperty); } set { this.SetValue(IsDragProperty, value); } } /// <summary> /// 按钮的定位位置 /// </summary> public Point CurrentPos { get { return (Point)this.GetValue(CurrentPosProperty); } set { this.SetValue(CurrentPosProperty, value); } } /// <summary> /// 当前鼠标点在按钮上的位置 /// </summary> public Point ClickPos { get { return (Point)this.GetValue(ClickPosProperty); } set { this.SetValue(ClickPosProperty, value); } } }
- MainWindow的XAML的部分代码
<Window x:Class="Demo.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:Demo" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525" x:Name="mainWindow"> <Canvas x:Name="canvas" Background="Aqua" Margin="0,0,36,9"> <local:DragButton x:Name="btn" Canvas.Left="173" Canvas.Top="64" Width="80" Height="30" Content="拖拽"/> </Canvas> </Window>
- MainWindow的C#后台部分代码
/// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); //添加事件 this.btn.AddHandler(Button.MouseLeftButtonDownEvent, new MouseButtonEventHandler(this.MouseButtonLeftDown), true); this.canvas.AddHandler(Canvas.MouseLeftButtonUpEvent, new MouseButtonEventHandler(this.CanvasButtonLeftUp), true); this.canvas.AddHandler(Canvas.MouseMoveEvent, new MouseEventHandler(this.Canvas_MouseMove),true); this.btn.CurrentPos = new Point((double)this.btn.GetValue(Canvas.LeftProperty), (double)this.btn.GetValue(Canvas.TopProperty)); } /// <summary> /// 区域移动事件 /// </summary> private void Canvas_MouseMove(object sender, MouseEventArgs e) { if(this.btn.IsDrag) { Point offsetPoint = e.GetPosition(this.canvas); double xOffset = offsetPoint.X - this.btn.CurrentPos.X - this.btn.ClickPos.X; double yOffset = offsetPoint.Y - this.btn.CurrentPos.Y - this.btn.ClickPos.Y; Rectangle rect = LogicalTreeHelper.FindLogicalNode(this, "rect") as Rectangle; TranslateTransform transform = (TranslateTransform)rect.RenderTransform; transform.X += xOffset; transform.Y += yOffset; this.btn.CurrentPos = new Point(offsetPoint.X- this.btn.ClickPos.X, offsetPoint.Y- this.btn.ClickPos.Y); } } /// <summary> /// 鼠标左键按下 /// </summary> private void MouseButtonLeftDown(object sender, MouseButtonEventArgs e) { if(!this.btn.IsDrag) { this.btn.ClickPos = e.GetPosition(this.btn); VisualBrush visualBrush = new VisualBrush(this.btn); Rectangle rect = new Rectangle() { Width = this.btn.ActualWidth, Height = this.btn.Height, Fill = visualBrush, Name = "rect" }; rect.SetValue(Canvas.LeftProperty, this.btn.GetValue(Canvas.LeftProperty)); rect.SetValue(Canvas.TopProperty, this.btn.GetValue(Canvas.TopProperty)); rect.RenderTransform = new TranslateTransform(0d, 0d); rect.Opacity = 0.6; this.canvas.Children.Add(rect); this.btn.IsDrag = true; } } /// <summary> /// 区域鼠标左键抬起 /// </summary> private void CanvasButtonLeftUp(object sender, MouseButtonEventArgs e) { if (this.btn.IsDrag) { this.btn.SetValue(Canvas.LeftProperty, this.btn.CurrentPos.X); this.btn.SetValue(Canvas.TopProperty, this.btn.CurrentPos.Y); Rectangle rect = LogicalTreeHelper.FindLogicalNode(this, "rect") as Rectangle; this.canvas.Children.Remove(rect); this.btn.IsDrag = false; } } }
四. 原理图
五. 运行效果
六. 工程代码
以上是关于WPF实现鼠标拖动控件并带有中间动效的主要内容,如果未能解决你的问题,请参考以下文章