c#:winform从一个toolstriptool上拖动一个图标到一个自定义usercontrol内。
效果:

在一个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内。的更多相关文章
- Winform自定义控件在界面上拖动、滚动鼠标。。会闪烁的解决方法
环境说明: 项目中有一个基类窗体BaseForm,有一个自定义控件TextBoxBase,两个控件都做了一些独特常规的封装和重写,在TextBoxBase中有一点重绘的下划线,发现在窗体运行之后, ...
- 用vue的自定义组件写了一个拖拽 组件,局部的 只能在自定义元素内的
简单实现 没有做兼容<!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- 从tabBarController的一个item上的控制器跳转到另一个item上的控制器
先从习惯性的tabBarController开始,很多应用的外框都是用这个开始的,而从tabBarController的一个item上的控制器跳转到另一个上的,往往都是直接通过点击tabBar上的不同 ...
- 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 ...
- ZeroMQ接口函数之 :zmq_recvmsg – 从一个socket上接收一个消息帧
ZeroMQ 官方地址 :http://api.zeromq.org/4-1:zmq-recvmsg zmq_recvmsg(3) ØMQ Manual - ØMQ/4.1.0 Nam ...
- ZeroMQ接口函数之 :zmq_sendmsg – 从一个socket上发送一个消息帧
ZeroMQ 官方地址 :http://api.zeromq.org/4-1:zmq-sendmsg zmq_sendmsg(3) ØMQ Manual - ØMQ/4.1.0 Name ...
- ZeroMQ接口函数之 :zmq_send_const – 从一个socket上发送一个固定内存数据
ZeroMQ API 目录 :http://www.cnblogs.com/fengbohello/p/4230135.html ——————————————————————————————————— ...
- 【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 ...
- 我需要在Web上完成一个图片上传的功能
我需要在Web上完成一个图片上传的功能. 这个页面需要能从手机中选择图片上传. 首先,这个页面是从微信上面触发的,所以修改了微信的的入口地址,增加了身份识别号作为传参. 跳转到页面的时候,页面先检查身 ...
随机推荐
- Python yield使用
https://www.ibm.com/developerworks/cn/opensource/os-cn-python-yield/ 您可能听说过,带有 yield 的函数在 Python 中被称 ...
- How AOT compares to a traditional JIT compiler
Ahead-of-Time (AOT) compilation is in contrast to Just-in-Time compilation (JIT). In a nutshell, .NE ...
- What is the largest TCP/IP network port number allowable for IPv4
69 down vote The largest port number is an unsigned short 2^16-1: 65535 A registered port is one ass ...
- GIS中的数据库.gdb与.mdb的区别
gdb是文件地理数据库,mdb是个人地理数据库,都是数据库文件类型. 个人地理数据库,是以access数据库为基础的个人将数据库格式mdb,可以存储不超过2G的文件,只适合Windows系统下: 文件 ...
- ibatis.net:第七天,QueryWithRowDelegate
xml <statement id="FindOrdersByCustomer" parameterClass="string" resultClass= ...
- spring源代码分析
预初始化beanDefaultListableBeanFactory preInstantiateSingletons
- 使用devenv.exe自动编译项目
因为手游项目使用的是cocos2d-x lua进行开发,在打PC版本提交测试时,有一些环境配置的地方需要进行改动,出包的时候比较麻烦,先修改文件再生成.如果能自动打包,每次打包之前将需要修改的文件进行 ...
- 在SQLite中使用事务
使用SQLiteDatabase的beginTransaction()方法可以开启一个事务,程序执行到endTransaction() 方法时会检查事务的标志是否为成功,如果为成功则提交事务,否则回滚 ...
- Apache Ant 简介和配置
Apache Ant 简介 Apache Ant是目前事实上的Java应用的标准build脚本工具.使它大受欢迎的一个主要愿意是它的和灵活,允许程序员创建自己的Task来对Ant进行扩展. ...
- Guava CharMatcher
概述 CharMatcher提供了多种对字符串处理的方法, 它的主要意图有: 1. 找到匹配的字符 2. 处理匹配的字符 CharMatcher内部主要实现包括两部分: 1. 实现了大量公用内部类, ...