效果:

在一个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. 将网桥的配置写进去/etc/sysconfig/network-scripts/ifcfg-xxx

    有时候需要使用网桥命令比如brctl设置一些网桥的属性,而这些方式能否同样写进去配置文件使其永久开机生效. 答案是不行的,也同样找过Ubuntu的,其实Ubuntu可以实现,参考:http://man ...

  2. POJ 1741 Tree (树分治入门)

    Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 8554   Accepted: 2545 Description ...

  3. JTAG – A technical overview and Timing

    This document provides you with interesting background information about the technology that underpi ...

  4. IEnumerable和IQueryable的区别以及背后的ExpressionTree表达式树

    关于IEnumerable和IQueryable的区别,这事还要从泛型委托Func<T>说起.来看一个简单的泛型委托例子: class Program { static void Main ...

  5. Linux init 0-6 启动级别

    原文地址:http://blog.sina.com.cn/s/blog_5f8e8d9801010wlr.html 原文地址:[转]Linux init 0-6 启动级别作者:流水清风 init 0- ...

  6. iOS 程序插件及功能动态更新思路

    所用框架及语言 iOS客户端-Wax(开发愤怒的小鸟的连接Lua 和 Objc的框架),Lua,Objc, 服务端-Java(用于返回插件页面) 工具框架链接地址:Wax - https://gith ...

  7. pthread_join与pthread_detach细节问题

    http://www.360doc.com/content/13/0106/09/9171956_258497083.shtml pthread_t    pthr; pthread_create(& ...

  8. android studio每次启动都要在fetching Android sdk compoment information停好久 怎么解决?

    网上有人给出了方案:1)进入刚安装的Android Studio目录下的bin目录.找到idea.properties文件,用文本编辑器打开.2)在idea.properties文件末尾添加一行: d ...

  9. SpringMVC从Controller跳转到还有一个Controller

    1. 需求背景 需求:spring MVC框架controller间跳转,需重定向.有几种情况:不带參数跳转.带參数拼接url形式跳转,带參数不拼接參数跳转,页面也能显示. 本来以为挺简单的一件事情. ...

  10. 架构:Introducing Expert Systems and Distributed Architecure

    原文地址:http://www.yourenterprisearchitect.com/2011/10/introducing-service-bus.html.   Expert Systems. ...