WPF控件拖动
支持任意方向拖动/水平方向拖动/垂直方向拖动
public enum DragDirection { [Description("任意")] Any, [Description("水平")] Horizontal, [Description("垂直")] Vertical, } public class ControlDragExtends : DependencyObject { public static int GetMaxX(DependencyObject obj) { return (int)obj.GetValue(MaxXProperty); } public static void SetMaxX(DependencyObject obj, int value) { obj.SetValue(MaxXProperty, value); } public static int GetMaxY(DependencyObject obj) { return (int)obj.GetValue(MaxYProperty); } public static void SetMaxY(DependencyObject obj, int value) { obj.SetValue(MaxYProperty, value); } public static int GetMinX(DependencyObject obj) { return (int)obj.GetValue(MinXProperty); } public static void SetMinX(DependencyObject obj, int value) { obj.SetValue(MinXProperty, value); } public static int GetMinY(DependencyObject obj) { return (int)obj.GetValue(MinYProperty); } public static void SetMinY(DependencyObject obj, int value) { obj.SetValue(MinYProperty, value); } public static DragDirection GetDragDirection(DependencyObject obj) { return (DragDirection)obj.GetValue(DragDirectionProperty); } public static void SetDragDirection(DependencyObject obj, DragDirection value) { obj.SetValue(DragDirectionProperty, value); } public static bool GetEnableDragMove(DependencyObject obj) { return (bool)obj.GetValue(EnableDragMoveProperty); } public static void SetEnableDragMove(DependencyObject obj, bool value) { obj.SetValue(EnableDragMoveProperty, value); } // Using a DependencyProperty as the backing store for DragDirection. This enables animation, styling, binding, etc... public static readonly DependencyProperty MaxYProperty = DependencyProperty.Register("MaxY", typeof(int), typeof(ControlDragExtends), new PropertyMetadata(int.MaxValue)); // Using a DependencyProperty as the backing store for DragDirection. This enables animation, styling, binding, etc... public static readonly DependencyProperty MaxXProperty = DependencyProperty.Register("MaxX", typeof(int), typeof(ControlDragExtends), new PropertyMetadata(int.MaxValue)); // Using a DependencyProperty as the backing store for DragDirection. This enables animation, styling, binding, etc... public static readonly DependencyProperty MinYProperty = DependencyProperty.Register("MinY", typeof(int), typeof(ControlDragExtends), new PropertyMetadata(0)); // Using a DependencyProperty as the backing store for DragDirection. This enables animation, styling, binding, etc... public static readonly DependencyProperty MinXProperty = DependencyProperty.Register("MinX", typeof(int), typeof(ControlDragExtends), new PropertyMetadata(0)); // Using a DependencyProperty as the backing store for DragDirection. This enables animation, styling, binding, etc... public static readonly DependencyProperty DragDirectionProperty = DependencyProperty.Register("DragDirection", typeof(DragDirection), typeof(ControlDragExtends), new PropertyMetadata(DragDirection.Any)); /// <summary> /// 回车/空格 /// </summary> public static readonly DependencyProperty EnableDragMoveProperty = DependencyProperty.RegisterAttached("EnableDragMove", typeof(bool), typeof(ControlDragExtends), new PropertyMetadata(false , OnEnableDragMove)); private static void OnEnableDragMove(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (e.NewValue != null) { var element = d as FrameworkElement; if (element == null) return; if ((bool)e.NewValue) { element.PreviewMouseDown += Element_PreviewMouseDown; element.PreviewMouseMove += Element_PreviewMouseMove; element.PreviewMouseUp += Element_PreviewMouseUp; } } } private static void Element_PreviewMouseDown(object sender, MouseButtonEventArgs e) { var c = sender as Control; _isMouseDown = true; _mouseDownPosition = e.GetPosition(null); Console.WriteLine(_mouseDownPosition); var transform = c.RenderTransform as TranslateTransform; if (transform == null) { transform = new TranslateTransform(); c.RenderTransform = transform; } _mouseDownControlPosition = new Point(transform.X, transform.Y); c.CaptureMouse(); } //鼠标是否按下 static bool _isMouseDown = false; //鼠标按下的位置 static Point _mouseDownPosition; //鼠标按下控件的位置 static Point _mouseDownControlPosition; private static void Element_PreviewMouseMove(object sender, MouseEventArgs e) { if (_isMouseDown) { var element = sender as FrameworkElement; if (element == null) return; var transform = element.RenderTransform as TranslateTransform; if (transform == null) return; var pos = e.GetPosition(null); var dp = pos - _mouseDownPosition; var newX = _mouseDownControlPosition.X + dp.X; var newY = _mouseDownControlPosition.Y + dp.Y; switch (GetDragDirection(element)) { case DragDirection.Horizontal: newX = Math.Max(GetMinX(element), newX); newX = Math.Min(GetMaxX(element), newX); newY = transform.Y; break; case DragDirection.Vertical: newY = Math.Max(GetMinY(element), newY); newY = Math.Min(GetMaxY(element), newY); newX = transform.X; break; case DragDirection.Any: default: break; } transform.X = newX; transform.Y = newY; } } private static void Element_PreviewMouseUp(object sender, MouseButtonEventArgs e) { var c = sender as Control; _isMouseDown = false; c.ReleaseMouseCapture(); } }
使用
<Grid> <Button HorizontalAlignment="Left" Margin="20" Content="拖动我" Width="100" Height="45" local:ControlDragExtends.EnableDragMove="True" ></Button> <Button x:Name="ButtonTest" local:ControlDragExtends.EnableDragMove="True" local:ControlDragExtends.DragDirection="Vertical" local:ControlDragExtends.MaxY="100" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="20,20" Content="附加拖动" Width="100" Height="45" ></Button> <Button x:Name="ButtonTestMaxX" local:ControlDragExtends.EnableDragMove="True" local:ControlDragExtends.DragDirection="Horizontal" local:ControlDragExtends.MaxX="500" local:ControlDragExtends.MinX="-1000" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="20,20" Content="附加拖动" Width="100" Height="45" ></Button> </Grid>
效果