很多时候我们会有这样的需求:一个窗体中有两个GRID,两个GRID中数据表结构差不多,我们要把一个GRID中的数据加入到另一个GRID中。一般的做法是新增一个导入或导出按钮,选择目标行后,通过按钮来触发事件,实现两个GRID中数据的增减。

嘿嘿,但是,如果我们能够在选中目标行后,直接用鼠标将选中的行拖拽到另一个GRID中是不是比较酷一点呢。

下面,我们就来看看如何实现它。

首先,创建示例数据。

我们还是用上一节:玩转DataGridView之行的展开与收缩的数据脚本,再用它新建两张表就行。

select * into Department_A from Department where DparentId=1
select * into Department_B from Department where DparentId=2

说一下思路:我们要实现的效果是在源Grid中选中行后,按住鼠标左键不放,将选中的行从源Grid中拖出,拖入到目标Grid中。其中所作的动作有四个:

1.选中行(可以单行或多行)

2.拖拽行

3.从源Grid中移除选中行(其实也可以不移除,看实际需求了,本例中将行从Grid中移除了)

4.目标Grid中新增选中行。

我们来一一分析。我在项目中建了两个Grid:sourceGrid即源,targetGrid即目标。

1.选中行

我们必需先要有一个全局变量来保存选中的行。

private DataGridViewSelectedRowCollection sourceRowCollection = null;//用来保存选中的行

给sourceRowCollection赋值当然是在sourceGrid_MouseDown事件中了。这里我们还必需要保证鼠标点击在有效区域才能给sourceRowCollection赋值。

这里有用到一个类HitTestInfo,NND,不知道微软为什么这样命名,害我找了很久。这个类可以获取当前鼠标所在的RowIndex和ColumnIndex

 private void sourceGrid_MouseDown(object sender, MouseEventArgs e)
{
//捕获鼠标点击区域的信息
DataGridView.HitTestInfo hitTestInfo= this.sourceGrid.HitTest(e.X, e.Y); if (e.X < 30 && hitTestInfo.RowIndex > -1)
{
if (this.sourceGrid.SelectedRows.Count > 0)
{
sourceRowCollection = this.sourceGrid.SelectedRows;
}
}
else
sourceRowCollection = null;
}

2.拖拽行

拖拽行就要用到一个很重要的方法:DoDragDrop,它有参数,一个是要拖拽的数据,一个要实现的效果。重要的是调用了后DoDragDrop可以触发目标控件(本例中是targetGrid)的DragOver、DragDrop等事件。当然前提是你的目标控件的AllowDrop为True。我之前就是因为AllowDrop没有设置为true,没有触发DragOver事件,害我瞎找了好久的原因。

关于DoDragDrop,参考:http://msdn.microsoft.com/zh-cn/library/ie/system.windows.forms.control.dodragdrop.aspx这里更详细的介绍,也有一个很好的例子。

我们在sourceGrid_MouseMove中去调用DoDragDrop方法:

 private void sourceGrid_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (sourceRowCollection != null)
{
DragDropEffects effect = this.sourceGrid.DoDragDrop(sourceRowCollection, DragDropEffects.Move);
if (effect == DragDropEffects.Move)
{
//在sourceGrid中移除选中行
foreach (DataGridViewRow row in sourceRowCollection)
{
this.sourceGrid.Rows.Remove(row);
}
//将sourceRowCollection重新置空
sourceRowCollection = null;
}
}
}
}

注意:effect == DragDropEffects.Move会在目标控件的DragDrop等事件执行完后再执行。
移动到目标窗体时,会触发targetGrid_DragOver事件,我们在这里设置DragDropEffects的值.

private void targetGrid_DragOver(object sender, DragEventArgs e)
{
if (!e.Data.GetDataPresent(typeof(DataGridViewSelectedRowCollection)))
{ e.Effect = DragDropEffects.None;
return;
}
else
{
e.Effect = DragDropEffects.Move; //这个值会返回给DoDragDrop方法
}
}

拖拽完成时,会触发DragDrop,我们在这里将拖拽的行赋给targetGrid

3.从源Grid中移除选中行

移除选中行已经在sourceGrid_MouseMove事件中了,即:

if (effect == DragDropEffects.Move)
{
//在sourceGrid中移除选中行
foreach (DataGridViewRow row in sourceRowCollection)
{
this.sourceGrid.Rows.Remove(row);
}
//将sourceRowCollection重新置空
sourceRowCollection = null;
}

4.目标Grid中新增选中行

新增行的代码也在targetGrid_DragDrop中,因为这个在拖拽完成时触发。这里我们分新增与插入的情况,详见上面的代码。

最后说明一下,我只做了界面上的两个GRID中数据的增减,并没有将更改保存到数据库中,大家有兴趣的可以自己去实现一下。

PS:貌似同一个窗体中的两个GRID不能有相同的列名,这点微软的做法让我很不爽,绑定数据的时候我不得不多写一个方法。

源代码:DataGridDemo,拖拽窗体即项目中的MoveGridForm

DataGridView拖动到TreeView的更多相关文章

  1. C#如何自定义DataGridViewColumn来显示TreeView

    我们可以自定义DataGridView的DataGridViewColumn来实现自定义的列,下面介绍一下如何通过扩展DataGridViewColumn来实现一个TreeViewColumn 1 T ...

  2. Windows窗体控件实现内容拖放(DragDrop)功能

    一.将控件内容拖到其他控件 在开发过程中,经常会有这样的要求,拖动一个控件的数据到另外一个控件中.例如将其中一个ListBox中的数据拖到另一个ListBox中.或者将DataGridView中的数据 ...

  3. 分享两种实现Winform程序的多语言支持的解决方案

    因公司业务需要,需要将原有的ERP系统加上支持繁体语言,但不能改变原有的编码方式,即:普通程序员感受不到编码有什么不同.经过我与几个同事的多番沟通,确定了以下两种方案: 方案一:在窗体基类中每次加载并 ...

  4. S2---深入.NET平台和C#编程的完美总结

    1.NET简单解说 l 面向对象提升 OOP(Object Oriented  Programming)面向对象编程 AOP:(Aspache  Oriented Programming):面向切面编 ...

  5. 网络电视精灵~分析~~~~~~简单工厂模式,继承和多态,解析XML文档,视频项目

    小总结: 所用技术: 01.C/S架构,数据存储在XML文件中 02.简单工厂模式 03.继承和多态 04.解析XML文档技术 05.深入剖析内存中数据的走向 06.TreeView控件的使用 核心: ...

  6. Blend 修改TreeViewItem样式

    Blend 修改TreeViewItem样式 1.用Blend for Visual Studio 2019 新建Wpf项目,拖动一个TreeView控件到Grid上 <Grid> < ...

  7. WPF开发快速入门【7】WPF的拖放功能(Drag and Drop)

    概述 本文描述WPF的拖放功能(Drag and Drop). 拖放功能涉及到两个功能,一个就是拖,一个是放.拖放可以发生在两个控件之间,也可以在一个控件自己内部拖放.假设界面上有两个控件,一个Tre ...

  8. C# 控件,MenuStrip,statusStrip,contextMenuStrip,ImageList, Listview,MonthCalendar、DataGridView,combobox,textbox,DateTimePicker,treeview,picturebox、toolStrip,radioButton,TableLayoutPanel

    一.菜单栏 1)MenuStrip 菜单栏 选择工具栏控件:menuStrip C# Menustrip控件的常用属性用法详解 C#WinForm应用程序——添加菜单栏MenuStrip] 1.通过右 ...

  9. WinForm中TreeView控件实现鼠标拖动节点(可实现同级节点位置互换,或拖到目标子节点)

    ;//1:不同级, 不为1:拖同级 private void treeView1_ItemDrag(object sender, ItemDragEventArgs e) { if (e.Button ...

随机推荐

  1. delphi.指针.应用----应用重要 多看 多练

    来自:http://www.cnblogs.com/qiusl/p/4026459.html ----------------------------------------------------- ...

  2. python批量下载图片3

    import urllib.request import os def url_open(url): req = urllib.request.Request(url) req.add_header( ...

  3. synchronized 修饰static方法

    •1.依靠对象锁锁定 初始化一个对象时,自动有一个 对象锁. synchronized {普通方法}依靠对象锁工作,多线程访问synchronized方法,一旦某个进程抢得锁之后,其他的进程只有排队对 ...

  4. hdu 5188(带限制的01背包)

    zhx and contest Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)T ...

  5. hdu 1147(线段相交)

    Pick-up sticks Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  6. rm 命令(删除文件和目录)

    rm是常用的命令,该命令的功能为删除一个目录中的一个或多个文件或目录,它也可以将某个目录及其下的所有文件及子目录均删除.对于链接文件,只是删除了链接,原有文件均保持不变. rm是一个危险的命令,使用的 ...

  7. 常用的WebService一览表

    天气预报Web服务,数据来源于中国气象局Endpoint :http://www.webxml.com.cn/WebServices/WeatherWebService.asmxDisco       ...

  8. 【转】requests、BeautifulSoup使用总结

    转自,https://www.cnblogs.com/wupeiqi/articles/6283017.html  ---- Python标准库中提供了:urllib.urllib2.httplib等 ...

  9. BZOJ 1185: [HNOI2007]最小矩形覆盖-旋转卡壳法求点集最小外接矩形(面积)并输出四个顶点坐标-备忘板子

    来源:旋转卡壳法求点集最小外接矩形(面积)并输出四个顶点坐标 BZOJ又崩了,直接贴一下人家的代码. 代码: #include"stdio.h" #include"str ...

  10. ACM数论-欧几里得与拓展欧几里得算法

    欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数. 基本算法:设a=qb+r,其中a,b,q,r都是整数,则gcd(a,b)=gcd(b,r),即gcd(a,b)=gcd(b,a%b). ...