现在有一个按钮btn1,要动态创建出一个btn2,需要btn2点击时调用btn1的点击。

在delphi中这种操作很简单:btn2.onClick:=btn1.onClick,因为onClick就是个属性,和name、width、height一样。

但是c#不能直接访问,这就麻烦了,

匿名委托,例子:

  1. //循环把所有菜单条目加到左侧
  2. Image img=null, imgDefaultDa = null, imgDefaultXiao = Image.FromFile(s + "菜单小项.png");
  3. foreach (ToolStripMenuItem mnu in mnu_Main.Items)
  4. { //循环遍历所有节点
  5. IconPanel m = new IconPanel();
  6. bar.AddBand(mnu.Text, m);
  7. //下级
  8. foreach (object o in mnu.DropDownItems)
  9. {
  10. ToolStripMenuItem mnuSub = null;
  11. if (o is ToolStripSeparator)
  12. {}
  13. else if (o is ToolStripMenuItem)
  14. {
  15. mnuSub = o as ToolStripMenuItem;
  16. img = mnuSub.Image;
  17. if (img == null) img = imgDefaultXiao;
  18. //Delegate[] ev = gsClass.getComponentEventDelegates(mnuSub, "Click", "EventHandler");
  19. //新建小项,难点是把这个菜单的click点击赋值给他
  20. PanelIcon btn = m.AddIcon(mnuSub.Text, img, delegate(object sender, EventArgs e) { mnuSub.PerformClick(); });
  21. }
  22. }
  23. }

参考一下:http://www.jb51.net/article/18150.htm

顺路带上c#的outLookBar、xp风格的菜单:

代码如下:

  1. using System;
  2. using System.Drawing;
  3. using System.Windows.Forms;
  4.  
  5. namespace iPublic
  6. {
  7.  
  8. /// <summary>
  9. /// outLook、 xp风格的菜单条,左侧,网上下来修改的,作者不知道是谁
  10. /// i'm 力生智能周承昊。20161226
  11. /// </summary>
  12. public class OutlookBar : Panel
  13. {
  14. private int buttonHeight;
  15. private int selectedBand;
  16. private int selectedBandHeight;
  17. public int 顶部位置偏移 = ; //zch,20161226
  18. public int 底部位置偏移 = ;
  19.  
  20. public int ButtonHeight
  21. {
  22. get
  23. {
  24. return buttonHeight;
  25. }
  26.  
  27. set
  28. {
  29. buttonHeight = value;
  30. // do recalc layout for entire bar
  31. }
  32. }
  33.  
  34. public int SelectedBand
  35. {
  36. get
  37. {
  38. return selectedBand;
  39. }
  40. set
  41. {
  42. SelectBand(value);
  43. }
  44. }
  45.  
  46. public OutlookBar()
  47. {
  48. buttonHeight = ;
  49. selectedBand = ;
  50. selectedBandHeight = ;
  51. }
  52.  
  53. public void Initialize()
  54. {
  55. // parent must exist!
  56. Parent.SizeChanged += new EventHandler(SizeChangedEvent);
  57. }
  58.  
  59. public void AddBand(string caption, ContentPanel content)
  60. {
  61. content.outlookBar = this;
  62. int index = Controls.Count;
  63. BandTagInfo bti = new BandTagInfo(this, index);
  64. BandPanel bandPanel = new BandPanel(caption, content, bti);
  65. Controls.Add(bandPanel);
  66. UpdateBarInfo();
  67. RecalcLayout(bandPanel, index);
  68. }
  69.  
  70. public void SelectBand(int index)
  71. {
  72. selectedBand = index;
  73. RedrawBands();
  74. }
  75.  
  76. private void RedrawBands()
  77. {
  78. for (int i = ; i < Controls.Count; i++)
  79. {
  80. BandPanel bp = Controls[i] as BandPanel;
  81. RecalcLayout(bp, i);
  82. }
  83. }
  84.  
  85. private void UpdateBarInfo()
  86. {
  87. selectedBandHeight = ClientRectangle.Height - (Controls.Count * buttonHeight);
  88. }
  89.  
  90. private void RecalcLayout(BandPanel bandPanel, int index)
  91. {
  92. int vPos = (index <= selectedBand) ? buttonHeight * index : buttonHeight * index + selectedBandHeight;
  93. int height = selectedBand == index ? selectedBandHeight + buttonHeight : buttonHeight;
  94.  
  95. // the band dimensions
  96. bandPanel.Location = new Point(, vPos);
  97. bandPanel.Size = new Size(ClientRectangle.Width, height);
  98.  
  99. // the contained button dimensions
  100. bandPanel.Controls[].Location = new Point(, );
  101. bandPanel.Controls[].Size = new Size(ClientRectangle.Width, buttonHeight);
  102.  
  103. // the contained content panel dimensions
  104. bandPanel.Controls[].Location = new Point(, buttonHeight);
  105. bandPanel.Controls[].Size = new Size(ClientRectangle.Width - , height - );
  106. }
  107.  
  108. private void SizeChangedEvent(object sender, EventArgs e)
  109. {
  110. Size = new Size(Size.Width, ((Control)sender).ClientRectangle.Size.Height - 顶部位置偏移 - 底部位置偏移);
  111. UpdateBarInfo();
  112. RedrawBands();
  113. }
  114.  
  115. }
  116.  
  117. internal class BandPanel : Panel
  118. {
  119. public BandPanel(string caption, ContentPanel content, BandTagInfo bti)
  120. {
  121. BandButton bandButton = new BandButton(caption, bti);
  122. Controls.Add(bandButton);
  123. Controls.Add(content);
  124. }
  125. }
  126.  
  127. internal class BandTagInfo
  128. {
  129. public OutlookBar outlookBar;
  130. public int index;
  131.  
  132. public BandTagInfo(OutlookBar ob, int index)
  133. {
  134. outlookBar = ob;
  135. this.index = index;
  136. }
  137. }
  138.  
  139. internal class BandButton : Button
  140. {
  141. private BandTagInfo bti;
  142.  
  143. public BandButton(string caption, BandTagInfo bti)
  144. {
  145. Text = caption;
  146. FlatStyle = FlatStyle.Standard;
  147. Visible = true;
  148. this.bti = bti;
  149. Click += new EventHandler(SelectBand);
  150. }
  151.  
  152. private void SelectBand(object sender, EventArgs e)
  153. {
  154. bti.outlookBar.SelectBand(bti.index);
  155. }
  156. }
  157.  
  158. public abstract class ContentPanel : Panel
  159. {
  160. public OutlookBar outlookBar;
  161.  
  162. public ContentPanel()
  163. {
  164. // initial state
  165. Visible = true;
  166. }
  167. }
  168.  
  169. /// <summary>
  170. /// 主菜单项
  171. /// </summary>
  172. public class IconPanel : ContentPanel
  173. {
  174. protected int iconSpacing;
  175. protected int margin;
  176.  
  177. public int IconSpacing
  178. {
  179. get
  180. {
  181. return iconSpacing;
  182. }
  183. }
  184.  
  185. public int Margin
  186. {
  187. get
  188. {
  189. return margin;
  190. }
  191. }
  192.  
  193. public IconPanel()
  194. {
  195. margin = ;
  196. iconSpacing = + + ; // icon height + text height + margin
  197. BackColor = Color.LightBlue;
  198. AutoScroll = true;
  199. }
  200.  
  201. public PanelIcon AddIcon(string caption, Image image, EventHandler onClickEvent)
  202. { //添加小项按钮
  203. int index = Controls.Count / ; // two entries per icon
  204. PanelIcon result = new PanelIcon(this, image, index, onClickEvent);
  205. Controls.Add(result);
  206. Size sz = (image == null ? new Size(, ) : image.Size);
  207. //
  208. Label label = new Label();
  209. label.Text = caption;
  210. label.Visible = true;
  211. label.Location = new Point(, margin + sz.Height + index * iconSpacing);
  212. label.Size = new Size(Size.Width, );
  213. label.TextAlign = ContentAlignment.TopCenter;
  214. if (onClickEvent != null) label.Click += onClickEvent;
  215. label.Tag = result;
  216. Controls.Add(label);
  217. //
  218. return result;
  219. }
  220.  
  221. }
  222.  
  223. public class PanelIcon : PictureBox
  224. {
  225. public int index;
  226. public IconPanel iconPanel;
  227.  
  228. private Color bckgColor;
  229. private bool mouseEnter;
  230.  
  231. public int Index { get { return index; } }
  232.  
  233. public PanelIcon(IconPanel parent, Image image, int index, EventHandler onClickEvent)
  234. { //新建按钮项
  235. this.index = index;
  236. this.iconPanel = parent;
  237. Image = image;
  238. Visible = true;
  239. Size sz = (image == null ? new Size(, ) : image.Size);
  240. Location = new Point(iconPanel.outlookBar.Size.Width / - sz.Width / ,
  241. iconPanel.Margin + index * iconPanel.IconSpacing);
  242. Size = sz;
  243. if (onClickEvent != null) Click += onClickEvent;
  244. Tag = this;
  245.  
  246. MouseEnter += new EventHandler(OnMouseEnter);
  247. MouseLeave += new EventHandler(OnMouseLeave);
  248. MouseMove += new MouseEventHandler(OnMouseMove);
  249.  
  250. bckgColor = iconPanel.BackColor;
  251. mouseEnter = false;
  252. }
  253.  
  254. private void OnMouseMove(object sender, MouseEventArgs args)
  255. { //鼠标移动
  256. if ((args.X < Size.Width - ) &&
  257. (args.Y < Size.Width - ) &&
  258. (!mouseEnter))
  259. {
  260. BackColor = Color.LightCyan;
  261. BorderStyle = BorderStyle.FixedSingle;
  262. Location = Location - new Size(, );
  263. mouseEnter = true;
  264. }
  265. }
  266.  
  267. private void OnMouseEnter(object sender, EventArgs e)
  268. {
  269. }
  270.  
  271. private void OnMouseLeave(object sender, EventArgs e)
  272. { //鼠标离开
  273. if (!mouseEnter) return;
  274. //
  275. BackColor = bckgColor;
  276. BorderStyle = BorderStyle.None;
  277. Location = Location + new Size(, );
  278. mouseEnter = false;
  279. }
  280.  
  281. }
  282.  
  283. #region //调用的例子代码
  284. public class 调用的例子代码
  285. {
  286.  
  287. private void loadLeftMenuBar(Form form)
  288. { //加载左侧菜单树
  289. //mnu_Main.Visible = false;
  290. object o = form.Controls.Find("mnu_Main", true), o2 = form.Controls.Find("sts_Main", true);
  291. if (o2 == null) o2 = form.Controls.Find("stb_Main", true);
  292. MenuStrip mnu_Main = (o == null ? null : o as MenuStrip);
  293. StatusStrip sts_Main = (o2 == null ? null : o2 as StatusStrip);
  294. string s = _iDefine.getRootPath() + "\\images\\";
  295. //初始化
  296. OutlookBar outlookBar = new OutlookBar();
  297. if (mnu_Main != null) outlookBar.顶部位置偏移 = (!mnu_Main.Visible ? : * (mnu_Main.Height + ));
  298. if (sts_Main != null) outlookBar.底部位置偏移 = sts_Main.Height + ;
  299. outlookBar.Location = new Point(, outlookBar.顶部位置偏移);
  300. outlookBar.Size = new Size(, form.ClientSize.Height - outlookBar.顶部位置偏移 - outlookBar.底部位置偏移);
  301. outlookBar.BorderStyle = BorderStyle.FixedSingle;
  302. form.Controls.Add(outlookBar);
  303. outlookBar.Initialize();
  304. //大块
  305. IconPanel iconPanel1 = new IconPanel();
  306. IconPanel iconPanel2 = new IconPanel();
  307. IconPanel iconPanel3 = new IconPanel();
  308. outlookBar.AddBand("Outlook Shortcuts", iconPanel1);
  309. outlookBar.AddBand("我的桌面", iconPanel2);
  310. outlookBar.AddBand("Other Shortcuts", iconPanel3);
  311. //小项
  312. iconPanel1.AddIcon("Outlook Today", Image.FromFile(s + "img1.ico"), new EventHandler(PanelEvent));
  313. iconPanel1.AddIcon("Calendar", Image.FromFile(s + "img2.ico"), new EventHandler(PanelEvent));
  314. iconPanel1.AddIcon("Contacts", Image.FromFile(s + "img3.ico"), new EventHandler(PanelEvent));
  315. iconPanel1.AddIcon("Tasks", Image.FromFile(s + "img4.ico"), new EventHandler(PanelEvent));
  316.  
  317. iconPanel2.AddIcon("ABC", Image.FromFile(s + "img4.ico"), new EventHandler(PanelEvent));
  318.  
  319. iconPanel3.AddIcon("DEFD", Image.FromFile(s + "img4.ico"), new EventHandler(PanelEvent));
  320. //选中第一项
  321. outlookBar.SelectBand();
  322. }
  323.  
  324. public void PanelEvent(object sender, EventArgs e)
  325. {
  326. Control ctrl = (Control)sender;
  327. PanelIcon panelIcon = ctrl.Tag as PanelIcon;
  328. MessageBox.Show("#" + panelIcon.Index.ToString(), "Panel Event");
  329. }
  330.  
  331. }
  332. #endregion
  333.  
  334. }

Gs_Class中获取所有Delegate的代码:

  1. #region//取一个控件的事件托管清单:getComponentEventDelegates
  2. /// <summary>
  3. /// 取一个控件的事件托管清单,例如想判断一个GridView是否定义了PageIndexChanging事件
  4. /// 从CSDN搜来的:http://blog.csdn.net/zxkid/archive/2006/12/15/1444396.aspx
  5. /// </summary>
  6. /// <param name="component">组件对象实例</param>
  7. /// <param name="EventName">事件的名称,如:Click</param>
  8. /// <param name="EventHandlerTypeName">事件委托类型,如"ItemClickEventHander"</param>
  9. /// <returns></returns>
  10. public static Delegate[] getComponentEventDelegates(object component, string EventName, string EventHandlerTypeName)
  11. {
  12. //取控件的类型、属性列表、事件托管列表、头字段列表
  13. Type componentType = component.GetType();
  14. PropertyInfo eventsPropertyInfo = componentType.GetProperty("Events", BindingFlags.Instance | BindingFlags.NonPublic);
  15. EventHandlerList eventHanlderList = eventsPropertyInfo.GetValue(component, null) as EventHandlerList;
  16. FieldInfo HeadFieldInfo = eventHanlderList.GetType().GetField("head", BindingFlags.Instance | BindingFlags.NonPublic);
  17. object HeadObject = HeadFieldInfo.GetValue(eventHanlderList);
  18. //
  19. do
  20. {
  21. FieldInfo[] fieldInfoList = componentType.GetFields(BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic);
  22. foreach (FieldInfo fieldInfo in fieldInfoList)
  23. {
  24. object fieldValue = fieldInfo.GetValue(component);
  25. if (fieldValue != null)
  26. {
  27. Type fieldType = fieldValue.GetType();
  28. if (fieldType.Name == EventHandlerTypeName && (fieldValue as Delegate) != null)
  29. {
  30. return (fieldValue as Delegate).GetInvocationList();
  31. }
  32. else if (fieldType.Name == typeof(Object).Name)
  33. {
  34. if (fieldInfo.Name.IndexOf(EventName, StringComparison.OrdinalIgnoreCase) > -)
  35. {
  36. if (HeadObject != null)
  37. {
  38. Delegate delegateObject = eventHanlderList[fieldValue];
  39. if (delegateObject != null)
  40. return delegateObject.GetInvocationList();
  41. }
  42. }
  43. }
  44. }
  45. }
  46. componentType = componentType.BaseType;
  47. }
  48. while (componentType != null); //循环结束
  49.  
  50. //
  51. if (HeadObject == null) return null; //没有
  52. object ListEntry = HeadObject;
  53. Type ListEntryType = ListEntry.GetType();
  54. FieldInfo handlerFieldInfo = ListEntryType.GetField("handler", BindingFlags.Instance | BindingFlags.NonPublic);
  55. FieldInfo keyFieldInfo = ListEntryType.GetField("key", BindingFlags.Instance | BindingFlags.NonPublic);
  56. FieldInfo nextFieldInfo = ListEntryType.GetField("next", BindingFlags.Instance | BindingFlags.NonPublic);
  57.  
  58. while (ListEntry != null)
  59. {
  60. Delegate handler = handlerFieldInfo.GetValue(ListEntry) as Delegate;
  61. object key = keyFieldInfo.GetValue(ListEntry);
  62. ListEntry = nextFieldInfo.GetValue(ListEntry);
  63.  
  64. if (handler != null && handler.GetType().Name == EventHandlerTypeName)
  65. return handler.GetInvocationList();
  66. }
  67. return null;
  68. }
  69. #endregion

转载请注明:海宏软件原创。

C#动态创建两个按钮,btn2复制btn1的Click事件,匿名委托的更多相关文章

  1. [转]android:动态创建多个按钮 及 批量设置监听

    之前投机取巧,先创建好多个按钮,再根据需要的数量进行部分隐藏,不过还是逃不过呀. 这样根本无法批量地 findId,批量地 设置监听. 所以今天还是认认真真地研究回“动态创建按钮”,终于,通过不断尝试 ...

  2. Android开发之动态创建多个按钮

    //获取屏幕大小,以合理设定 按钮 大小及位置 DisplayMetrics dm = new DisplayMetrics(); getWindowManager().getDefaultDispl ...

  3. JS: javascript 点击事件执行两次js问题 ,解决jquery绑定click事件出现点击一次执行两次问题

    javascript 点击事件执行两次js问题 在JQuery中存在unbind()方法,先解绑再添加点击事件,解决方案为: $(".m-layout-setting").unbi ...

  4. WinForms中动态给treeView的节点添加ContextMenuStrip,并绑定Click事件

    生成ContextMenuStrip var docMenu = new ContextMenuStrip(); ToolStripMenuItem deleteMenuItem = new Tool ...

  5. jquery利用appendTo动态创建元素

    动态创建元素可以说是DOM中常做的事情,下面我来介绍在jquery中利用appendTo来动态创建元素,有需要的朋友可参考参考. 当HTML字符串是没有属性的元素是, 内部使用document.cre ...

  6. [C# 基础知识系列]专题五:当点击按钮时触发Click事件背后发生的事情 (转载)

    当我们在点击窗口中的Button控件VS会帮我们自动生成一些代码,我们只需要在Click方法中写一些自己的代码就可以实现触发Click事件后我们Click方法中代码就会执行,然而我一直有一个疑问的—— ...

  7. table动态添加的tr 其click事件在IE兼容模式中不执行 jquery 1.9 的live事件 和获取 first last

    http://www.css88.com/jqapi-1.9/first-of-type/index.html#p=//www.css88.com/jqapi-1.9/last-child-selec ...

  8. MFC动态创建按钮,并在按钮上实现位图的切换显示

    动态创建按钮,并在按钮中添加位图,通过单击按钮显示不同的位图,可设置为显示按钮按下和弹起两种状态.只要判断a值从而输入不同的响应代码. 1.在头文件中添加: CButton *pBtn; 2.在初始化 ...

  9. MFC动态创建对话框中的按钮控件并创建其响应消息

    转自:http://www.cnblogs.com/huhu0013/p/4626686.html 动态按钮(多个)的创建: 1.在类中声明并定义按钮控件的ID #define IDC_D_BTN 1 ...

随机推荐

  1. Oracle汇总笔记

    http://gzf_PC:1158/em数据库配置文件已经安装到 D:\WorkC,同时其他选定的安装组件也已经安装到 D:\WorkC\oracle.iSQL*Plus URL 为:http:// ...

  2. iOS基础 - 数据存取

    一.iOS应用数据存储的常用方式 XML属性列表(plist)归档 Preference(偏好设置) NSKeyedArchiver归档 SQLite3 Core Data 二.应用沙盒 每个iOS应 ...

  3. 监听JVM关闭

    使用Runtime的addShutdownHook(thread)方法: for(int i=0; i<5; i++){ System.out.println(i); } Thread th = ...

  4. linux下telnet mysql的3306断口,提示Can't connect to MySQL server on localhost (110)

    新购买的阿里云ECS服务器,食用lnmp环境,安装完毕后,telnet localhost 3306提示Can't connect to MySQL server on localhost (110) ...

  5. ubuntu 下面手动安装jdk

    ubuntu 下面手动安装jdk 刚才在ubuntu安装jdk和eclipse,感觉主要安装jdk比较麻烦,记录一下笔记以备后面查看 先在官网上下载jdk的tar包:http://www.oracle ...

  6. 使ie6的漂浮栏滑动右侧滚动条的时候不抖动

    body {_background-attachment: fixed;}html {_background-image: url(about:blank);}

  7. TPL相关

    C#中的Timer System.Windows.Forms.TimerSystem.Threading.Timer System.Timers.Timer 1.System.Windows.Form ...

  8. uva 408 Uniform Generator

    Uniform Generator  Computer simulations often require random numbers. One way to generate pseudo-ran ...

  9. jQuery中bind与live的用法与区别

    首先介绍这两个方法之前,我们常用的是click()方法 $("a").click(function() { alert("hello"); }); click( ...

  10. [wp8游戏] cocos2d-x v2.2 + VS2013 环境搭建

    [wp8游戏] cocos2d-x v2.2 + VS2013 环境搭建 by:唐小崇 http://www.cnblogs.com/tangchong 从cocos2d-x v2.1.4 以来,co ...