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("1", 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(0, 0, 100, 20); 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 = 0; void WorkPlace_DragDrop(object sender, DragEventArgs e) { if ((e.Data.GetDataPresent(typeof(Button)))) { //拖放完毕之后,自动生成新控件 Button btn = new Button(); btn.SetBounds(e.X, e.Y, 100, 50); 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; } }
注意事项:
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实例。 } // 旧代码。。。。 } }
基础才是编程人员应该深入研究的问题,比如:
1)List/Set/Map内部组成原理|区别
2)mysql索引存储结构&如何调优/b-tree特点、计算复杂度及影响复杂度的因素。。。
3)JVM运行组成与原理及调优
4)Java类加载器运行原理
5)Java中GC过程原理|使用的回收算法原理
6)Redis中hash一致性实现及与hash其他区别
7)Java多线程、线程池开发、管理Lock与Synchroined区别
8)Spring IOC/AOP 原理;加载过程的。。。
【+加关注】。