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>

效果

浙公网安备 33010602011771号