C# wpf 实现Grid内控件拖动 基于C# wpf 实现Grid内控件拖动详情
Alfred-N 人气:0想了解基于C# wpf 实现Grid内控件拖动详情的相关内容吗,Alfred-N在本文为您仔细讲解C# wpf 实现Grid内控件拖动的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:C#,wpf,实现Grid内控件拖动,wpf,实现Grid内控件拖动,Grid内控件拖动,下面大家一起来学习吧。
前言:
有一些业务场景中我们需要拖动控件,在Grid
中就可以实现控件拖动,通过设置Margin
属性即可,根据鼠标的移动,设置相应的Margin
的Left
、Top,当然有时也不是直接设置的,需要根据HorizontalAlignment
、VerticalAlignment
值有不同的计算方法。
一、如何实现?
1.注册鼠标事件
拖动的控件需要注册3个鼠标事件分别是,鼠标按下、鼠标移动、鼠标弹起。
以Button为例:
<Button PreviewMouseDown="Button_MouseDown" PreviewMouseMove="Button_MouseMove" PreviewMouseUp="Button_MouseUp"> </Button>
2.记录位置
在鼠标按下事件中记录位置。
//鼠标是否按下 bool _isMouseDown = false; //鼠标按下的位置 Point _mouseDownPosition; //鼠标按下控件的Margin Thickness _mouseDownMargin; //鼠标按下事件 private void Button_MouseDown(object sender, MouseButtonEventArgs e) { var c = sender as Control; _isMouseDown = true; _mouseDownPosition = e.GetPosition(this); _mouseDownMargin = c.Margin; }
3.跟随鼠标移动
鼠标按下后移动鼠标,控件需要跟随鼠标移动。根据HorizontalAlignment
、VerticalAlignment
值不同,计算Margin的方式也不同。
private void Button_MouseMove(object sender, MouseEventArgs e) { if (_isMouseDown) { var c = sender as Control; var pos = e.GetPosition(this); var dp = pos - _mouseDownPosition; double left, top, right, bottom; if (c.HorizontalAlignment == HorizontalAlignment.Stretch|| c.HorizontalAlignment == HorizontalAlignment.Center) //中央移动距离是双倍 { left= _mouseDownMargin.Left+ dp.X * 2; right = _mouseDownMargin.Right; } else if(c.HorizontalAlignment== HorizontalAlignment.Left) //左边是正常距离 { left = _mouseDownMargin.Left + dp.X ; right = _mouseDownMargin.Right; } else //右边是右边距距离 { left = _mouseDownMargin.Left; right = _mouseDownMargin.Right - dp.X; } if (c.VerticalAlignment == VerticalAlignment.Stretch || c.VerticalAlignment == VerticalAlignment.Center) //中央移动距离是双倍 { top = _mouseDownMargin.Top+ dp.Y* 2; bottom = _mouseDownMargin.Bottom; } else if (c.VerticalAlignment == VerticalAlignment.Top) //顶部是正常距离 { top = _mouseDownMargin.Top + dp.Y ; bottom = _mouseDownMargin.Bottom; } else //底部是底边距距离 { top = _mouseDownMargin.Top ; bottom = _mouseDownMargin.Bottom- dp.Y; } c.Margin = new Thickness(left, top, right, bottom); } }
4.恢复标识
鼠标弹起后需要恢复标识,让控件不再跟随鼠标移动。
private void Button_MouseUp(object sender, MouseButtonEventArgs e) { if (_isMouseDown) { _isMouseDown = false; //移动了的控件不响应点击事件(此处根据具体需求) e.Handled = true; } }
二、示例
示例代码:
<Window x:Class="WpfControlMove.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:WpfControlMove" mc:Ignorable="d" Title="MainWindow" Height="360" Width="640"> <Grid> <Button Width="120" Height="50" Content="移动" PreviewMouseDown="Button_MouseDown" PreviewMouseMove="Button_MouseMove" PreviewMouseUp="Button_MouseUp"> </Button> </Grid> </Window>
效果预览:
总结:
本文说明了Grid中控件拖动的方法。方法采用了记录鼠标位置以及控件位置的方法来确保准确的相对位置。如果是采用只记录鼠标位置,计算时通过控件内部坐标差值累加,这样会产生累计误差,除非取整运算,但取整与dpi有可能产生不兼容。总的来说,本方法采用准确的位置计算方式,而且还根据不同停靠采用相应的计算方法,适用性较好。
加载全部内容