效果:

在一个winform工程中,添加一个ToolStrip然后给它添加一个ToolStripButton(tsbStart,它就是红色框圈选的图标)

this.toolStripTools = new System.Windows.Forms.ToolStrip();
this.tsbStart = new System.Windows.Forms.ToolStripButton();

,当点击tsbStart并拖动到工作区(图中下边空白区,它是一个panel,panel动态添加了一个usercontrol),拖动进入工作区(usercontrol)时触发事件WorkPlace_DragEnter(object sender, DragEventArgs e),把鼠标e.Effect = DragDropEffects.Copy;。结束拖动时,在工作区(usercontroll)范围内监控到WorkPlace_DragDrop(object sender, DragEventArgs e)时,在工作区动态添加一个控件,完成拖动效果。

实现代码:

main窗体代码:

     public Main()
{
InitializeComponent();
} private void Main_Load(object sender, EventArgs e)
{
if (this.wpClient != null)
wpClient.CloseFlow(); // 重新加载窗体时,清空窗体中的控件。
this.plClient.Controls.Clear(); wpClient = new WorkPlace("", UserId, UserName);
wpClient.WorkFlowCaption = "Hello WorkFlow Designer...";
wpClient.CanEdit = true;
wpClient.State = "修改"; // 添加wpClient对象到plClient控件区域内。
this.plClient.Controls.Add(this.wpClient); // Main窗體的工具欄圖標生效為可用狀態。
this.toolStripTools.Enabled = true;
} private void tsbStart_MouseDown(object sender, MouseEventArgs e)
{
//左键的话,标志位为true(表示拖拽开始)
if ((e.Button == System.Windows.Forms.MouseButtons.Left))
{
//形成拖拽效果,移动+拷贝的组合效果
Button button = new Button();
button.SetBounds(, , , );
button.Text = "button ";
button.DoDragDrop(button, (DragDropEffects.Copy | DragDropEffects.Move)); //形成拖拽效果,移动+拷贝的组合效果
}
}

workspace自定义控件代码:

        public WorkPlace()
{
InitializeComponent();
// 如果允許結構拖動事件必須設置為true,否則無法結束拖動事件。
// 自定義控件自身支持接受拖拽来的控件
this.AllowDrop = true;
this.DragEnter += new DragEventHandler(WorkPlace_DragEnter);
this.DragDrop += new DragEventHandler(WorkPlace_DragDrop);
} public WorkPlace(string workFlowId, string userId, string userName)
: this()
{
this.WorkFlowId = workFlowId;
this.UserId = userId;
this.UserName = userName;
} /// <summary>
/// 關閉窗體,關閉窗體時需要判定是否當前工作內容已經保存,否則提示確認信息。
/// </summary>
public void CloseFlow()
{ } void WorkPlace_DragEnter(object sender, DragEventArgs e)
{
//当Button被拖拽到WinForm上时候,鼠标效果出现
if ((e.Data.GetDataPresent(typeof(Button))))
{
e.Effect = DragDropEffects.Copy;
}
} int count = ;
void WorkPlace_DragDrop(object sender, DragEventArgs e)
{
if ((e.Data.GetDataPresent(typeof(Button))))
{
//拖放完毕之后,自动生成新控件
Button btn = new Button();
btn.SetBounds(e.X, e.Y, , );
btn.Location = this.PointToClient(new Point(e.X, e.Y));
//用这个方法计算出客户端容器界面的X,Y坐标。否则直接使用X,Y是屏幕坐标
this.Controls.Add(btn);
btn.Text = "按钮" + count.ToString();
count = count + ;
}
}

注意事项:

1)workplace自定义控件内部必须把属性AllowDrop设置true,否则不触发DragDown,DargDrop事件。

    this.AllowDrop = true;

2)如何在事件中把传递的值给转义出来:如果采用强制转化,发现转化结果为null

       Button bt = (Button)e.Data; // 转化结果为null

3)正确的转化结果:

        void WorkPlace_DragDrop(object sender, DragEventArgs e)
{
if ((e.Data.GetDataPresent(typeof(Button))))
{
FieldInfo info, info2, info3;
object obj, obj2, obj3;
info = e.Data.GetType().GetField("innerData", BindingFlags.NonPublic | BindingFlags.Instance);
obj = info.GetValue(e.Data); info2 = obj.GetType().GetField("data", BindingFlags.NonPublic | BindingFlags.Instance);
obj2 = info2.GetValue(obj); System.Collections.Hashtable dataItems = (obj2 as System.Collections.Hashtable);
foreach (var dataItem in dataItems)
{
System.Collections.DictionaryEntry dictEntry = (System.Collections.DictionaryEntry)dataItem;
object key = dictEntry.Key;
object value = dictEntry.Value; info3 = value.GetType().GetField("data", BindingFlags.Public | BindingFlags.Instance);
obj3 = info3.GetValue(value); Button btnInstance = obj3 as Button; // 此处转化成功,成功获取到传递进来的button实例。
} // 旧代码。。。。
}
}

c#:winform从一个toolstriptool上拖动一个图标到一个自定义usercontrol内。的更多相关文章

  1. Winform自定义控件在界面上拖动、滚动鼠标。。会闪烁的解决方法

    环境说明:   项目中有一个基类窗体BaseForm,有一个自定义控件TextBoxBase,两个控件都做了一些独特常规的封装和重写,在TextBoxBase中有一点重绘的下划线,发现在窗体运行之后, ...

  2. 用vue的自定义组件写了一个拖拽 组件,局部的 只能在自定义元素内的

    简单实现 没有做兼容<!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  3. 从tabBarController的一个item上的控制器跳转到另一个item上的控制器

    先从习惯性的tabBarController开始,很多应用的外框都是用这个开始的,而从tabBarController的一个item上的控制器跳转到另一个上的,往往都是直接通过点击tabBar上的不同 ...

  4. ZeroMQ接口函数之 :zmq_recv – 从一个socket上接收一个消息帧

    ZeroMQ 官方地址 :http://api.zeromq.org/4-1:zmq_recv zmq_recv(3)        ØMQ Manual - ØMQ/4.1.0 Name zmq_r ...

  5. ZeroMQ接口函数之 :zmq_recvmsg – 从一个socket上接收一个消息帧

    ZeroMQ 官方地址 :http://api.zeromq.org/4-1:zmq-recvmsg zmq_recvmsg(3)         ØMQ Manual - ØMQ/4.1.0 Nam ...

  6. ZeroMQ接口函数之 :zmq_sendmsg – 从一个socket上发送一个消息帧

    ZeroMQ 官方地址 :http://api.zeromq.org/4-1:zmq-sendmsg zmq_sendmsg(3)        ØMQ Manual - ØMQ/4.1.0 Name ...

  7. ZeroMQ接口函数之 :zmq_send_const – 从一个socket上发送一个固定内存数据

    ZeroMQ API 目录 :http://www.cnblogs.com/fengbohello/p/4230135.html ——————————————————————————————————— ...

  8. 【Python + Selenium】Mock Testing 是啥?一个so上的高票答案。

    There are many kinds of testing which really made me confused. To be honest, I've never heard of som ...

  9. 我需要在Web上完成一个图片上传的功能

    我需要在Web上完成一个图片上传的功能. 这个页面需要能从手机中选择图片上传. 首先,这个页面是从微信上面触发的,所以修改了微信的的入口地址,增加了身份识别号作为传参. 跳转到页面的时候,页面先检查身 ...

随机推荐

  1. $.ajax 方法参数总是记不住,在这里记录一下

    jquery中的ajax方法参数总是记不住,这里记录一下. 1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. 2.type: 要求为String类型的参数,请求方式(p ...

  2. Ubuntu 16.04实现SSH无密码登录/免密登录/自动登录(ssh-keygen/ssh-copy-id)

    ssh-keygen:产生公钥与私钥(在~/.ssh) ssh-copy-id:将本机的公钥复制到远程机器的authorized_keys文件中(在~/.ssh),ssh-copy-id也能让你有到远 ...

  3. android.os.handler(转)

    android.os.handler相关知识整理 Handler在android里负责发送和处理消息.它的主要用途有: 1)按计划发送消息或执行某个Runnanble(使用POST方法): 2)从其他 ...

  4. 依赖注入(DI)和控制反转(IOC)的理解,写的太好了。

    学习过spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...

  5. 大数据以及Hadoop相关概念介绍

    一.大数据的基本概念 1.1.什么是大数据 大数据指的就是要处理的数据是TB级别以上的数据.大数据是以TB级别起步的.在计算机当中,存放到硬盘上面的文件都会占用一定的存储空间,例如: 文件占用的存储空 ...

  6. centos7虚拟机(vmware)通过U盘传文件

    centos7虚拟机(vmware)通过U盘传文件 centos7虚拟机安装以后,WINDOWS给CENTOS7传文件,除了在CENTOS7安装SAMBA外,其实通过U盘也是可以的. CENTOS7对 ...

  7. vs已停止工作

    第一步: 开始-->所有程序-->Microsoft Visual Studio 2012-->VisualStudio Tools-->VS2012 开发人员命令提示(以管理 ...

  8. SQL:显示每天的小计,某一天没有记录也要显示

    对于这种需求,我们需要一个主表存储连续的日期,然后使用 left join 即可. declare @Daily table ( 日期 date ) declare @start date = '20 ...

  9. 盾牌第一至七季/全集The Shield迅雷下载

    英文译名The Shield,第1-7季(2002-2008)FX.本季看点:<盾牌>一部极具争议性的连续剧,打破了传统警匪片套路,刻画了性格复杂的警察,他们在与各种罪案做斗争的同时,也面 ...

  10. Table中collapseColumns,stretchColumns

    collapseColumns  设置需要被隐藏的列序号(序号从0开始) shrinkColumns     设置允许被首夺的列的序号(序号从0开始) stretchColumns    设置允许被拉 ...