以前一直使用C#2.0,这次为了开发MongoDB的工具,使用了C#4.0.因为用惯了VB,这个也是C#4的处女作了。
一直知道C#的扩展方法,今天第一次使用。。。。。。
现在在做的工具,是恨传统的桌面工具,在制作中发现上下文菜单项和主菜单项ToolStripMenuItem没有Clone的功能,这样的话,无法实现上下文菜单项和主菜单项的共用。
看了网上的一些例子,无非是做一个继承ToolStripMenuItem的新类,然后Copy属性。我的方法是做扩展方法,思路也差不多:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Windows.Forms; 6 using System.Reflection; 7 using System.ComponentModel; 8 namespace MagicMongoDBTool.Module 9 { 10 static class CloneMeunToolItem 11 { 12 /// <summary> 13 /// 复制菜单项目 14 /// </summary> 15 /// <param name="OrgMenuItem"></param> 16 /// <returns></returns> 17 public static ToolStripMenuItem Clone( this ToolStripMenuItem OrgMenuItem) 18 { 19 ToolStripMenuItem CloneMenuItem = new ToolStripMenuItem(); 20 // !!!typeof的参数必须是ToolStripMenuItem的基类!!!如果使用Control则不能取到值!!! 21 /// 感谢CSDN网友beargo在帖子【如何获取事件已定制方法名?】里面的提示,网上的例子没有说明这个问题 22 /// 坑爹啊。。。。。。。。 23 Delegate[] _List = GetObjectEventList(OrgMenuItem, " EventClick ", typeof(ToolStripItem)); 24 CloneMenuItem.Click += new EventHandler( 25 (x, y) => { _List[ 0].DynamicInvoke(x,y); } 26 ); 27 CloneMenuItem.Text = OrgMenuItem.Text; 28 return CloneMenuItem; 29 } 30 31 /// <summary> 32 /// 获取控件事件 zgke@sina.com qq:116149 33 /// </summary> 34 /// <param name="p_Control"> 对象 </param> 35 /// <param name="p_EventName"> 事件名 EventClick EventDoubleClick 这个需要看control.事件 是哪个类的名字是什么 </param> 36 /// <param name="p_EventType"> 如果是WINFROM控件 使用typeof(Control) </param> 37 /// <returns> 委托列 </returns> 38 public static Delegate[] GetObjectEventList( object p_Object, string p_EventName, Type p_EventType) 39 { 40 PropertyInfo _PropertyInfo = p_Object.GetType().GetProperty( " Events ", BindingFlags.Instance | BindingFlags.NonPublic); 41 if (_PropertyInfo != null) 42 { 43 object _EventList = _PropertyInfo.GetValue(p_Object, null); 44 if (_EventList != null && _EventList is EventHandlerList) 45 { 46 EventHandlerList _List = (EventHandlerList)_EventList; 47 FieldInfo _FieldInfo = p_EventType.GetField(p_EventName, BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.IgnoreCase); 48 if (_FieldInfo == null) return null; 49 Delegate _ObjectDelegate = _List[_FieldInfo.GetValue(p_Object)]; 50 if (_ObjectDelegate == null) return null; 51 return _ObjectDelegate.GetInvocationList(); 52 } 53 } 54 return null; 55 } 56 } 57 }
只是我想说一下,网络上很多代码,包括CSDN上的很多回答。基本上使用了同样的例子。
不过对于这个例子的解释完全没有。特别是哪个坑爹的如果是WINFROM控件 使用typeof(Control)。如果照着这个写的话,菜单项目是没有办法使用的。
正确的说法是 使用控件的 基类。
下面报告一下MongoDB工具的进度:
今天完成了数据3种方法展示的功能