现在有一个按钮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. Android中怎么去除标题栏详解

    怎么出去标题栏,我再另一个博客中亦有实例在这里再详细的解释一下,也让自己能更加巩固最简单也是小重要的东西. 这里有两种方法是比较好的... 第一种: 首先,在values中建一个theme.xml 代 ...

  2. ASP.NET MVC应用程序实现下载功能

    ASP.NET MVC应用程序实现下载功能 上次Insus.NET有在MVC应用程序实现了上传文件的功能<MVC应用程序显示上传的图片> http://www.cnblogs.com/in ...

  3. 关于 MVCC 的基础

    作为第一篇对 MVCC 的学习材料,以下内容翻译自 Wikipedia. 1. 什么是MVCC 1.1 基础概念 MVCC,Multi-Version Concurrency Control,多版本并 ...

  4. 排序算法的C#实现

    8种主要排序算法的C#实现   新的一年到了,很多园友都辞职要去追求更好的工作环境,我也是其中一个,呵呵! 最近闲暇的时候我开始重温一些常用的算法.老早就买了<算法导论>,一直都没啃下去. ...

  5. iOS基础 - 多媒体

    一.播放视频 iOS提供了叫做MPMoviePlayerController.MPMoviePlayerViewController的两个类,可以用来轻松播放视频 YouTobe就是用MPMovieP ...

  6. General Structure of Quartz.NET and How To Implement It

    General Structure of Quartz.NET and How To Implement It   General Structure of Quartz.NET and How To ...

  7. 《12个有趣的C语言问答》评析2

    <12个有趣的C语言问答>评析(2) 前文链接:http://www.cnblogs.com/pmer/p/3313913.html (没存盘,遭遇过热保护.至少4个问答的评论白写了.默哀 ...

  8. Object-c学习之路六(oc字符串文件读写)

    // // main.m // NSString // // Created by WildCat on 13-7-25. // Copyright (c) 2013年 wildcat. All ri ...

  9. Asp.net QueryString批量插入和更新

    public static string InsertOrUpdateQueryString(string[] keys, string[] values) { return InsertOrUpda ...

  10. Winform程序

    故事的开端是这样的,小白是一个程序员,他确实也是一个小白,目前还在程序员发展的道路上,兢兢业业的小心求学. 有一天,小白接到一个任务,完成一个Winform程序,附加一个功能就是可以读IC卡. 小白终 ...