效果:

在一个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. mysql慢查询日志功能的使用

    作用:mysql慢查询日志可监控有效率问题的SQL .. 一.开启mysql慢查询日志功能 1.查看是否开启 未使用索引的SQL记录日志查询 mysql> show variables like ...

  2. 华为S5300系列交换机限制特定IP可以登录Web

    针对Web管理可能有如下需求: 1.限制某个特定IP允许访问Web 2.默认修改80端口访问 那么针对上面的设置可以有效杜绝而已Web密码暴力破解,增强交换机安全等. 实现: 1.限制特定IP登录We ...

  3. [原创]用Charles模拟App各种网络带宽测试介绍

    [原创]用Charles模拟App各种网络带宽测试介绍 相信每个测试在进行自己公司App测试时,都会碰到一个问题,如何去模拟各种App在各种带宽下的测试情况,估计很少有公司直接去采用2g/3g/4g卡 ...

  4. Java怎样处理EXCEL的读取

    须要包:poi-3.5.jar.poi-ooxml-3.5.jar 实例: [java] view plaincopy public class ProcessExcel { private Work ...

  5. mybatis 详解

    http://www.cnblogs.com/ysocean/category/1007230.html

  6. [Winform]基于Emgu.CV人脸识别

    摘要 “OpenCV是一个开源的计算机视觉库.OpenCV采用C/C++语言编写,可以运行在Linux/Windows/Mac等操作系统上.OpenCV还提供了Python.Ruby.MATLAB以及 ...

  7. C#编程(六十五)----------表达式树

    表达式树 以前没听过表达式树,只听过表达式,而且听过Lambda表达式,首先介绍一下.NET里表达式树的核心概念:讲代码作为数据,他将一些代码表示为一个对象树,树中的每个节点本身都是一个表达式,不同的 ...

  8. 学习 HTML+CSS 的书籍推荐

    1.<CSS那些事儿> 本书专注于CSS技巧实例的讲解,由浅入深地分析了CSS样式在布局时所需要理解的原理.绕开随处可见的基础知识.网络中能随意搜索到的hack技巧,侧重原理分析,拓展读者 ...

  9. 【linux】linux下shell命令 多个变量在命令中的引用 以及重新赋值给新的变量

    原本的find命令: find /apps/Devops/jenkins/workspace/swapping/target/ -name '*swapping*.jar' 错误的命令: SOURCE ...

  10. android studio一直卡在Gradle:Executing tasks

    http://www.eoeandroid.com/forum.php?mod=viewthread&tid=554227 新建了个hello world项目,运行就卡在Gradle:Exec ...