基于C# wpf 实现Grid内控件拖动详情

目录
  • 一、如何实现?
    • 1.注册鼠标事件
    • 2.记录位置
    • 3.跟随鼠标移动
    • 4.恢复标识
  • 二、示例

前言:

有一些业务场景中我们需要拖动控件,在Grid中就可以实现控件拖动,通过设置Margin属性即可,根据鼠标的移动,设置相应的MarginLeft、Top,当然有时也不是直接设置的,需要根据HorizontalAlignmentVerticalAlignment值有不同的计算方法。

一、如何实现?

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.跟随鼠标移动

鼠标按下后移动鼠标,控件需要跟随鼠标移动。根据HorizontalAlignmentVerticalAlignment值不同,计算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有可能产生不兼容。总的来说,本方法采用准确的位置计算方式,而且还根据不同停靠采用相应的计算方法,适用性较好。

到此这篇关于基于C# wpf 实现Grid内控件拖动详情的文章就介绍到这了,更多相关C# wpf 实现Grid内控件拖动内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • c# WPF中通过双击编辑DataGrid中Cell的示例(附源码)

    背景 在很多的时候我们需要编辑DataGrid中每一个Cell,编辑后保存数据,原生的WPF中的DataGrid并没有提供这样的功能,今天通过一个具体的例子来实现这一个功能,在这个例子中DataGrid中的数据类型可能是多种多样的,有枚举.浮点类型.布尔类型.DateTime类型,每一种不同的类型需要双击以后呈现不同的效果,本文通过使用Xceed.Wpf.DataGrid这个动态控件库来实现这个功能,当前使用的Dll版本是2.5.0.0,不同的版本可能实现上面有差别,这个在使用的时候需要特别注意

  • 基于C# wpf 实现Grid内控件拖动详情

    目录 一.如何实现? 1.注册鼠标事件 2.记录位置 3.跟随鼠标移动 4.恢复标识 二.示例 前言: 有一些业务场景中我们需要拖动控件,在Grid中就可以实现控件拖动,通过设置Margin属性即可,根据鼠标的移动,设置相应的Margin的Left.Top,当然有时也不是直接设置的,需要根据HorizontalAlignment.VerticalAlignment值有不同的计算方法. 一.如何实现? 1.注册鼠标事件 拖动的控件需要注册3个鼠标事件分别是,鼠标按下.鼠标移动.鼠标弹起. 以But

  • C# wpf Canvas中实现控件拖动调整大小的示例

    目录 前言 一.功能说明 二.如何实现? 1.继承Adorner 2.使用Thumb 3.实现拖动逻辑 三.完整代码 四.使用示例 总结 前言 我们做图片编辑工具.视频编辑工具.或者画板有时需要实现控件缩放功能,比如图片或图形可以拉伸放大或缩小,实现这种功能通常需要8个点,对应4条边和4个角,在wpf中通常可以使用装饰器实现. 一.功能说明 8个点方放置在控件的8个方位上,通过拖动这些点对控件进行拉伸或缩小,示意图如下: 二.如何实现? 1.继承Adorner 通过装饰器的方式添加8个点在控件上

  • Android基于widget组件实现物体移动/控件拖动功能示例

    本文实例讲述了Android基于widget组件实现物体移动/控件拖动功能.分享给大家供大家参考,具体如下: package com.sky; import android.app.Activity; import android.os.Bundle; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickLi

  • WPF实现slide控件拖动完成后改变变量值

    WPF中使slide控件拖动完成后改变变量值这个问题一开始觉得还是挺简单的,网上也看到不少解决方案. 首先一个最简单最直接的方案就是自定义一个名为FinalValue的依赖属性.随后重载OnThumbDragCompleted函数,在Thumb控件完成拖动时改写FinalValue.代码如下 public class SliderIgnoreDelta : Slider { public int FinalValue { get { return (int)GetValue(FinalValue

  • WPF自定义选择年月控件详解

    本文实例为大家分享了WPF自定义选择年月控件的具体代码,供大家参考,具体内容如下 封装了一个选择年月的控件,XAML代码: <UserControl x:Class="SunCreate.CombatPlatform.Client.DateMonthPicker" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.micr

  • WPF中引入WindowsForms控件的方法

    本文实例讲述了WPF中引入WindowsForms控件的方法.分享给大家供大家参考,具体如下: 环境: [1]WindowsXP with SP3 [2]VS2008 with SP1 正文: Step1:在现有工程中引入Windows Forms 鼠标右键[References]->选择[Add Reference]->[.NET]标签页 加入[WindowsFormsIntegration]和[System.Windows.Forms]两项 Step2:在XAML文件里加入 [S2-1]加

  • 基于Bootstrap仿淘宝分页控件实现代码

    大家都应该上过淘宝的吧,没有上过淘宝的同学估计也没几个了,但是我相信大多数的人都是在淘宝上面买完东西就下线,很少有人会关注淘宝上的设计这类的,但是对于普通人这样还行,但是对于一个程序员这样就可不行了,因为博主本人是从事前端方面的工作,所以就通过仿照淘宝的设计样式,以求在技能上面能够有一个大的突破 一.淘宝分页控件了解 先上一张淘宝的分页图片: 根据上图中对淘宝分页控件的分析,我们大致上可以将淘宝分页控件分成两部分,一部分是核心部分,这一部分主要就是一个分页的核心功能,这个功能同时也是也是不可或缺

  • Repeater事件OnItemCommand取得行内控件的方法

    记录一下,主要是这句:TextBox txtNum = e.Item.FindControl("txtNum") as TextBox; Repeater真是太强了,太灵活.除了Repeater别的都不用. 复制代码 代码如下: <table>    <asp:Repeater ID="rptList" runat="server"OnItemCommand="rptList_ItemCommand">

  • WPF实现控件拖动的示例代码

    实现控件拖动的基本原理是对鼠标位置的捕获,同时根据鼠标按键的按下.释放确定控件移动的幅度和时机. 简单示例: 在Grid中有一个Button,通过鼠标事件改编Button的Margin属性,从而改变Button在Grid中的相对位置. <Grid Name="gd"> <Button Width=90 Height=30 Name="btn">button</Button> </Grid> 为Button控件绑定三个事

  • Android开发之基于RecycleView实现的头部悬浮控件

    RecyclerView是一种类似于ListView的一个滑动列表,但是RecyclerView和ListView相比,RecyclerView比ListView更好,RecyclerView支持横向滑动,RecyclerView没有点击事件,需要自己加入,还可以做出各种炫酷的效果动画,更符合高内聚低耦合, 前言 前几天看到一个RecycleView中筛选框滑动可以悬浮在头部的效果类似商机盒子中的商机模块. 本来想法很常规 通过Recycview装饰器来实现(刚开始是否定掉的感觉太难) 通过Re

随机推荐