原帖子:http://www.cd-aptech.com/Foundation_Detail.aspx?id=175
拖放操作向来比较受青睐,因为它操作简单,符合Windows用户的操作习惯,那么在WinForms里如何实现拖放呢?下面我将以最简单的两个PictureBox控件间的图片相互拖放来讲解。
要实现两个PictureBox控件间的图片相互拖放,只需要以下4步:
(1) 先设置两个PictureBox控件的AllowDrop属性(注意:PictureBox控件的属性列表里没有AllowDrop属性,我们可以通过代码来设置。但是在代码设置的时候,还是发现点不出来,这是正常的,我们硬设置进去)。
关键代码为:
this.picLeft.AllowDrop = true;
this.picRight.AllowDrop = true;
(2) 在两个PictureBox控件的MouseDown事件里开始拖放数据(这里是PictureBox显示的图片)。
关键代码为:
//判断是否按下鼠标左键
if (e.Button == MouseButtons.Left)
{
//从sender对象里取出源事件PictureBox控件
PictureBox picTemp = sender as PictureBox;
//判断事件源对象是否正显示了图片
if (picTemp.Image != null)
{
//开始拖放操作,并传递要拖动的数据以及拖放的类型(是移动操作还是拷贝操作)
picTemp.DoDragDrop(picTemp.Image,DragDropEffects.Move | DragDropEffects.Copy);
}
}
(3) 在两个PictureBox控件的DragEnter事件里检查拖放的数据。
关键代码为:
//检查拖动的数据是否适合于目标空间类型;若不适合,则拒绝放置。
if (e.Data.GetDataPresent(DataFormats.Bitmap)) {
//检查Ctrl键是否被按住
if (e.KeyState == Ctrl) {
//若Ctrl键被按住,则设置拖放类型为拷贝
e.Effect = DragDropEffects.Copy;
}
else
{
//若Ctrl键没有被按住,则设置拖放类型为移动
e.Effect = DragDropEffects.Move;
}
}
else
{
//若被拖动的数据不适合于目标控件,则设置拖放类型为拒绝放置
e.Effect = DragDropEffects.None;
}
(4) 在两个PictureBox控件的DragDrop事件里完成数据的拖放。
关键代码为:
//从sender对象里取出目标事件PictureBox控件
PictureBox picTemp = sender as PictureBox;
//从事件参数中取出拖动的数据,并转换为图象对象
picTemp.Image = e.Data.GetData(DataFormats.Bitmap) as Bitmap;
//若不是执行的拷贝操作
if (e.KeyState != Ctrl)
{
//且是把图片放置到picLeft控件,那么picRight控件显示的图片将被清除;反之亦然。
if (picTemp.Name == "picLeft")
{
this.picRight.Image = null;
}
else
{
this.picLeft.Image = null;
}
}
整个拖放操作完整代码为:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace ActionDemo
{
public partial class frmAction : Form
{
private const byte Ctrl = 8;//表示按住了Ctrl键(类似的还有Alt、Shift、鼠标左键、鼠标右键等键的常数定义,请查看MSDN)
public frmAction()
{
InitializeComponent();
}
//窗体加载事件
private void frmAction_Load(object sender, EventArgs e)
{
this.picLeft.Image = Image.FromFile("01.jpg");
this.picLeft.AllowDrop = true;
this.picRight.AllowDrop = true;
//绑定提示信息
this.tlPMessage.SetToolTip(this.picLeft, "同时按住Ctrl键将复制图片");
this.tlPMessage.SetToolTip(this.picRight, "同时按住Ctrl键将复制图片");
}
//鼠标按下事件
private void picLeft_MouseDown(object sender, MouseEventArgs e)
{
//判断是否按下鼠标左键
if (e.Button == MouseButtons.Left)
{
//从sender对象里取出源事件PictureBox控件
PictureBox picTemp = sender as PictureBox;
//判断事件源对象是否正显示了图片
if (picTemp.Image != null)
{
//开始拖放操作,并传递要拖动的数据以及拖放的类型(是移动操作还是拷贝操作)
picTemp.DoDragDrop(picTemp.Image,DragDropEffects.Move | DragDropEffects.Copy);
}
}
}
//在用鼠标将某项拖放到该控件的工作区时发生
private void picLeft_DragEnter(object sender, DragEventArgs e)
{
//检查拖动的数据是否适合于目标空间类型;若不适合,则拒绝放置。
if (e.Data.GetDataPresent(DataFormats.Bitmap)) {
//检查Ctrl键是否被按住
if (e.KeyState == Ctrl) {
//若Ctrl键被按住,则设置拖放类型为拷贝
e.Effect = DragDropEffects.Copy;
}
else
{
//若Ctrl键没有被按住,则设置拖放类型为移动
e.Effect = DragDropEffects.Move;
}
}
else
{
//若被拖动的数据不适合于目标控件,则设置拖放类型为拒绝放置
e.Effect = DragDropEffects.None;
}
}
//拖放操作完成时发生
private void picLeft_DragDrop(object sender, DragEventArgs e)
{
//从sender对象里取出目标事件PictureBox控件
PictureBox picTemp = sender as PictureBox;
//从事件参数中取出拖动的数据,并转换为图象对象
picTemp.Image = e.Data.GetData(DataFormats.Bitmap) as Bitmap;
//若不是执行的拷贝操作
if (e.KeyState != Ctrl)
{
//且是把图片放置到picLeft控件,那么picRight控件显示的图片将被清除;反之亦然。
if (picTemp.Name == "picLeft")
{
this.picRight.Image = null;
}
else
{
this.picLeft.Image = null;
}
}
}
}
}