http://www.cnblogs.com/imlions/p/3189773.html

在开发程序的时候,为了提高用户的使用体验,或满足相关用户的功能,总是离不开拖放功能。而本文是总结winform下的常用拖放操作。主要有

1.textbox接受拖放的文件 2.listbox允许用户自定义排序 3.listbox之间的拖放 4.控件的拖放 5.console的拖放问题

用户在进行拖放操作时,经过的步骤大体如下: 例如将A中的数据拖放的B中 鼠标点击A中的数据(MouseDown)->鼠标移动(MouseMove)->出源数据边界,即出A(DragLeave)->进入目标边界,进入B(DragEnter)->在B中移动,选择放数据的位置,即拖动效果(DragOver)->抬起鼠标(MouseDown)->将A数据放到B中,拖放结束。(DragDrop,所有的拖放都涉及DragDrop事件)。

下面的所有例子,都会使用到上面所列举的几个事件。

首先对目标组件set "AllowDrop" to true

一、textbox接受拖放的文件。为了方便用户的使用,这个应该是最常用到的操作。加入这个功能,可以使用户省去“打开文件对话框,然后选择文件”的操作。在这个例子中,我们不需要知道用户的点击,即选择了什么文件。只需要了解用户拖动文件进入Textbox(DragEnter),并松开鼠标,完成拖放(DragDrop)。主要涉及到两个事件。

DragEnter:在将对象拖入控件的边界时发生。判断是否是文件拖放

DragDrop:在完成拖放操作时发生。判断文件类型,只添加txt文件

首先添加一个textBox控件,将控件的属性设置为AllowDrop=True,Multiline=True 代码如下:

private void textBox1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
e.Effect = DragDropEffects.Copy;
}
} private void textBox1_DragDrop(object sender, DragEventArgs e)
{
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
foreach (string file in files)
{
if(Path.GetExtension(file)==".txt") //判断文件类型,只接受txt文件
{
textBox1.Text += file + "\r\n";
}
} }

二、listbox允许用户自定义排序。在一个listbox中的拖放操作,我们要知道用户选择了什么数据(MouseDown),要把数据放到哪里,即坐标(DragOver),完成拖放(DragDrop)。主要涉及的事件有3个 MouseDown:选择Listbox中的item DragOver: 鼠标的移动 DragDrop: 拖放完成。在鼠标当前位置插入数据

首先在窗体上加入Listbox控件,将AllowDrop属性设置为True 代码如下:

private void FrmListboxDragTest_Load(object sender, EventArgs e)
{
for (int i = 0; i <= 20; i++)
{
this.listBox1.Items.Add(string.Format("事件{0}",i));
}
} private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
if (this.listBox1.SelectedItem == null)
{
return;
}
//开始拖放操作,DragDropEffects为枚举类型。
//DragDropEffects.Move 为将源数据移动到目标数据
this.listBox1.DoDragDrop(this.listBox1.SelectedItem, DragDropEffects.Move);
} private void listBox1_DragOver(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Move;
} private void listBox1_DragDrop(object sender, DragEventArgs e)
{
Point point = listBox1.PointToClient(new Point(e.X, e.Y));
int index = this.listBox1.IndexFromPoint(point);
if (index < 0)
{
index = this.listBox1.Items.Count - 1;
}
//获取拖放的数据内容
object data = e.Data.GetData(typeof(string));
//删除元数据
this.listBox1.Items.Remove(data);
//插入目标数据
this.listBox1.Items.Insert(index, data);
}

三.listbox之间的拖放。因为是在Listbox之间拖放数据,所以涉及到两个控件。假如本例是将Listbox1中的数据拖放到Listbox2中。那涉及的事件有4个 Listbox1 中的MouseDown:选取Listbox1中的数据 Listbox2 中的DragEnter:拖放操作进入Listbox2 Listbox2 中的DragOver: 在Listbox2上移动 Listbox2 中的DragDrop: 拖放完毕,在Listbox2中显示数据

代码如下:

private void FrmTwoListboxDragTest_Load(object sender, EventArgs e)
{
for (int i = 0; i <= 20; i++)
{
this.listBox1.Items.Add(string.Format("listbox1中的数据{0}", i));
this.listBox2.Items.Add(string.Format("listbox2中的数据{0}", i));
}
} private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
if (listBox1.Items.Count == 0)
return; int index = listBox1.IndexFromPoint(e.X, e.Y);
string s = listBox1.Items[index].ToString();
listBox1.DoDragDrop(s, DragDropEffects.Copy);
} private void listBox2_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.StringFormat))
e.Effect = DragDropEffects.Copy;
} private void listBox2_DragOver(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.All;
} private void listBox2_DragDrop(object sender, DragEventArgs e)
{
Point point = listBox2.PointToClient(new Point(e.X, e.Y));
int index = this.listBox1.IndexFromPoint(point);
if (index < 0)
{
index = this.listBox1.Items.Count - 1;
}
object data = e.Data.GetData(typeof(string));
this.listBox1.Items.Remove(data);
this.listBox2.Items.Insert(index, data);
}

4.控件的拖放。以pictureBox为例。涉及的事件有 MouseDown 选取pictureBox,可以判断鼠标按键(左键还是右键等) MouseMove 移动鼠标到指定位置 MouseUp 释放鼠标按键,放下pictureBox

在进行控件移动的时候,需要明白pictureBox的坐标并不是鼠标的坐标,MouseDown只是在鼠标按下后执行一次,而MouseMove随着pictureBox的移动而不停的触发。

代码如下:

private bool _clicked = false;
private int _clickx;
private int _clicky;
private int _mouseDownCount = 1;
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (_clicked)
{
Point p = new Point();
p.X = e.X + pictureBox1.Left;
p.Y = e.Y + pictureBox1.Top;
pictureBox1.Left = p.X - _clickx;
pictureBox1.Top = p.Y - _clicky;
lblMouseMove.Text = string.Format("{0}:{1}", pictureBox1.Left, pictureBox1.Top);
}
} private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
_clicked = false;
lblMouseUp.Text = string.Format("{0}:{1}", e.X,e.Y);
} private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
pictureBox1.Left = e.X;
pictureBox1.Top = e.Y;
_clickx = e.X;
_clicky = e.Y;
lblMouseDown.Text = string.Format("{0}:{1}:{2}", e.X, e.Y,_mouseDownCount);
_clicked = true;
_mouseDownCount += 1;
}

五、console的拖放问题 console 的拖放时最简单的一种操作,因为console本身就支持拖放(如同cmd)。而我们所要做的只是添加一行代码,然后等待用户按下回车。例如:

string content=Console.ReadLine();
Console.WriteLine(content);
Console.ReadLine();

Ohter:

DragDropEffects 枚举

成员名称 说明
  All Copy   、Move 和 Scroll 效果的组合。
  Copy 将拖动源中的数据复制到放置目标。
  Link 将拖动源中的数据链接到放置目标。
  Move 将拖动源的数据移动到放置目标。
  None 放置目标不接受该数据。
  Scroll 拖动时可以滚动目标,以定位在目标中当前不可见的某个放置位置。

The only difference is the cursor, the user can tell from the cursor appearance whether your program will do a move or a copy.  The copy cursor has a +, the move cursor doesn't.

http://msdn.microsoft.com/zh-cn/library/system.windows.forms.dragdropeffects.aspx

http://stackoverflow.com/questions/10789027/whats-the-difference-between-dragdropeffects-copy-and-dragdropeffects-move

C# Winform 拖放操作的更多相关文章

  1. C# Winform 涉及的拖放操作总结

    在开发程序的时候,为了提高用户的使用体验,或满足相关用户的功能,总是离不开拖放功能.而本文是总结winform下的常用拖放操作.主要有 1.textbox接受拖放的文件2.listbox允许用户自定义 ...

  2. winform里操作打开在panel里的form窗体,子窗体操作同级子窗体或者父窗体的方法

    最近开始了一个winform项目,原先一直都是web项目.遇到个问题,就是在框架内,左侧和中间的main都是用panel来实现的form,就是把form窗体打开到panel里,实现左侧是导航,中间是操 ...

  3. nw.js如何处理拖放操作

    nw.js如何处理拖放操作 其实拖放(drag-drop)操作是Html5的功能,不是nw.js的内置API,那么我们采用Html5应用一般的处理方法就可以了. 首先我们看一下一个正常的页面,直接拖放 ...

  4. C#窗体WinForm 文件操作

    文件及文件夹操作 C/S:WinForm可以操作客户端文件 Client ServerB/S:浏览器服务 Brower Server 命名空间:using system .IO; 1. File类:文 ...

  5. C#窗体 WinForm 文件操作

    文件及文件夹操作 C/S:WinForm可以操作客户端文件 Client ServerB/S:浏览器服务 Brower Server 命名空间:using system .IO; 1. File类:文 ...

  6. Windows的拖放操作使用方法

    Windows的拖放操作使用方法

  7. FileZilla无法确定拖放操作的目标,由于shell未正确安装

    天有不测风云,突然间,用filezilla下载ftp上的文件到桌面的时候,提示"无法确定拖放操作目标.由于shell未正确安装" 解决办法很简单,执行如下几步就OK了 1.在CMD ...

  8. WinForm 文件操作

    文件及文件夹操作 C/S:WinForm可以操作客户端文件 Client ServerB/S:浏览器服务 Brower Server 命名空间:using system .IO; 1. File类:文 ...

  9. 背水一战 Windows 10 (73) - 控件(控件基类): UIElement - 拖放的基本应用, 手动开启 UIElement 的拖放操作

    [源码下载] 背水一战 Windows 10 (73) - 控件(控件基类): UIElement - 拖放的基本应用, 手动开启 UIElement 的拖放操作 作者:webabcd 介绍背水一战 ...

随机推荐

  1. Part 57 to 58 Why should you override ToString and Equal Method

    Part 57 Why should you override ToString Method sometimes you can override ToString method like that ...

  2. C# 输出24小时格式时间

    比如   MessageBox.Show(DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss")); 会输出  2014-4-3 5:08:4[1 ...

  3. Exchange 2010先决条件

    为了方便大家一步到位的进行学习,已将各种角色安装所需的先决条件给与总结了,但注意系统需求是2008 R2     1.对于执行客户端访问.集线器传输及邮箱角色典型安装的服务器            ( ...

  4. Jquery判断$("#id")获取的对象是否存在的方法

    如果是下面的 jquery 代码判断一个对象是否存在,是不能用的 if($("#id")){ }else{} 因为 $(“#id”) 不管对象是否存在都会返回 object . 正 ...

  5. 使用eBay API基本步骤介绍

    要开始使用eBay API,需要如下基本步骤: 1.    注册开发帐号: https://developer.ebay.com/join/Default.aspx 2.    选择API类型: eB ...

  6. [TimusACM][1258]程序员撞墙的问题

    (本文是从我的旧博客迁移过来的) 问题地址:http://acm.timus.ru/problem.aspx?space=1&num=1258 前几日在博客园看到这种在线测试的时候,有一种相见 ...

  7. socket.io问题,io.sockets.manager.rooms和io.sockets.clients('particular room')这两个函数怎么用?

    为什么我用nodejs用这个两个函数获取都会出错呢?是不是socket的api改了?请问现在获取房间数和当前房间的客户怎么获取?什么函数?谢谢!!急求!     网友采纳 版本问题.io.socket ...

  8. OC6_代理的基本概念

    // // Person.h // OC6_代理的基本概念 // // Created by zhangxueming on 15/6/24. // Copyright (c) 2015年 zhang ...

  9. NodeJs多进程和socket.io通讯-DEMO

    一.开启多进程 const os = require('os'); const cp = require('child_process'); const forkList = {}; const fo ...

  10. Different ways to invoke a shared object/share library(.so)

    在Linux中调用.so文件的方法有几种. 1.直接在编译的时候链接上. 2.dlopen/???