WPF 在Canvas拖动多个控件的独立移动的具体实现

    技术2022-07-13  68

    写这篇文章的理由:

    触发机制——单个功能点用时一个工作日的核心代码实现

    具体需求

    在Canvas画布上动态添加可移动的标签(就是实现截图功能的文本备注功能)。

    主要说移动多个控件功能,在网上找的移动功能都只支持一个文本的移动或者是多个控件同时移动,没有找到能够独立移动的,在此之上我做了一些改进,支持多个文本移动。

    UI代码:

    <Grid> <Canvas x:Name="canvas1"> <TextBlock Text="AAA" x:Name="text"></TextBlock> <TextBlock Text="BBB" x:Name="text1" Canvas.Left="100"></TextBlock> </Canvas> </Grid>

    后台实现主要利用了3个事件,TextBlock的MouseLeftButtonDown,Canvas的MouseLeftButtonUp和Canvas的MouseMove

    使用一个类变量的移动标志去控制滑动的开始和结束:

    使用一个类变量去保存当前移动的是哪个文本:

    //移动标志 bool isMoving = false; //保存当前移动的是哪个文本 TextBlock currentText;

    使用TextBlock 的Tag属性去保存文本移动时需要保存的值;

    1.点击文本时 文本当前的坐标值(startMovePosition);

    2.文本移动的长度坐标值(TotalTranslate);

    3.文本最终显示的坐标值(TempTranslate);

    为什么要用TextBlock的Tag属性去保存文本移动时需要保存的值呢?

    因为每一个文本移动时都是独立在移动的,不能因为这个文本移动而干扰到另外一个文本;而Tag的类型是Object,刚好可以保存我自定义的类型,能够实现每一个控件独立移动的核心就是这个tag属性所保存的值。

    TextBlockTag类:

    public class TextBlockTag { public TextBlockTag() { TotalTranslate = new TranslateTransform(); TempTranslate = new TranslateTransform(); } public TranslateTransform TotalTranslate { get; set; } public TranslateTransform TempTranslate { get; set; } public Point startMovePosition { get; set; } }

    构造函数:

    public MainWindow() { InitializeComponent(); text.MouseLeftButtonDown += Canvas1_MouseLeftButtonDown; text1.MouseLeftButtonDown += Canvas1_MouseLeftButtonDown; text.Tag = new TextBlockTag(); text1.Tag = new TextBlockTag(); canvas1.MouseLeftButtonUp += Canvas1_MouseLeftButtonUp; canvas1.MouseMove += Canvas1_MouseMove; canvas1.Focusable = true;//重要:默认条件下不接收鼠标事件 canvas1.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch; canvas1.VerticalAlignment = System.Windows.VerticalAlignment.Stretch; }

    TextBlock的MouseLeftButtonDown事件:

    private void Canvas1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { var text = sender as TextBlock; if (currentText != text) { currentText = new TextBlock(); currentText = text; } (currentText.Tag as TextBlockTag).startMovePosition = e.GetPosition(canvas1); isMoving = true; }

    Canvas的MouseLeftButtonUp事件:

    private void Canvas1_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { if (currentText == null) return; isMoving = false; Point endMovePosition = e.GetPosition(canvas1); //为了避免跳跃式的变换,单次有效变化 累加入 totalTranslate中。 (currentText.Tag as TextBlockTag).TotalTranslate.X += (endMovePosition.X - (currentText.Tag as TextBlockTag).startMovePosition.X); (currentText.Tag as TextBlockTag).TotalTranslate.Y += (endMovePosition.Y - (currentText.Tag as TextBlockTag).startMovePosition.Y); currentText = null; }

    Canvas的MouseMove事件:

    private void Canvas1_MouseMove(object sender, MouseEventArgs e) { if (isMoving && e.LeftButton == MouseButtonState.Pressed) { Point currentMousePosition = e.GetPosition(canvas1);//当前鼠标位置 Point deltaPt = new Point(0, 0); deltaPt.X = (currentMousePosition.X - (currentText.Tag as TextBlockTag).startMovePosition.X); deltaPt.Y = (currentMousePosition.Y - (currentText.Tag as TextBlockTag).startMovePosition.Y); (currentText.Tag as TextBlockTag).TempTranslate.X = (currentText.Tag as TextBlockTag).TotalTranslate.X + deltaPt.X; (currentText.Tag as TextBlockTag).TempTranslate.Y = (currentText.Tag as TextBlockTag).TotalTranslate.Y + deltaPt.Y; TransformGroup tfGroup = new TransformGroup(); tfGroup.Children.Add((currentText.Tag as TextBlockTag).TempTranslate); currentText.RenderTransform = tfGroup; } }

    文本移动功能就可以实现了,至于文本添加功能,指哪打哪,就不细说了很简单,要是想知道完整功能的实现可以私信我。 

    最后

    这个功能的实现,只是我基于网上的思路改进的,要是你们有什么其他更简单的实现思路,麻烦评论说一说,我们共同学习,共同进步

    Processed: 0.011, SQL: 9