C#动态创建两个按钮,btn2复制btn1的Click事件,匿名委托
现在有一个按钮btn1,要动态创建出一个btn2,需要btn2点击时调用btn1的点击。
在delphi中这种操作很简单:btn2.onClick:=btn1.onClick,因为onClick就是个属性,和name、width、height一样。
但是c#不能直接访问,这就麻烦了,
匿名委托,例子:
- //循环把所有菜单条目加到左侧
- Image img=null, imgDefaultDa = null, imgDefaultXiao = Image.FromFile(s + "菜单小项.png");
- foreach (ToolStripMenuItem mnu in mnu_Main.Items)
- { //循环遍历所有节点
- IconPanel m = new IconPanel();
- bar.AddBand(mnu.Text, m);
- //下级
- foreach (object o in mnu.DropDownItems)
- {
- ToolStripMenuItem mnuSub = null;
- if (o is ToolStripSeparator)
- {}
- else if (o is ToolStripMenuItem)
- {
- mnuSub = o as ToolStripMenuItem;
- img = mnuSub.Image;
- if (img == null) img = imgDefaultXiao;
- //Delegate[] ev = gsClass.getComponentEventDelegates(mnuSub, "Click", "EventHandler");
- //新建小项,难点是把这个菜单的click点击赋值给他
- PanelIcon btn = m.AddIcon(mnuSub.Text, img, delegate(object sender, EventArgs e) { mnuSub.PerformClick(); });
- }
- }
- }
参考一下:http://www.jb51.net/article/18150.htm
顺路带上c#的outLookBar、xp风格的菜单:
代码如下:
- using System;
- using System.Drawing;
- using System.Windows.Forms;
- namespace iPublic
- {
- /// <summary>
- /// outLook、 xp风格的菜单条,左侧,网上下来修改的,作者不知道是谁
- /// i'm 力生智能周承昊。20161226
- /// </summary>
- public class OutlookBar : Panel
- {
- private int buttonHeight;
- private int selectedBand;
- private int selectedBandHeight;
- public int 顶部位置偏移 = ; //zch,20161226
- public int 底部位置偏移 = ;
- public int ButtonHeight
- {
- get
- {
- return buttonHeight;
- }
- set
- {
- buttonHeight = value;
- // do recalc layout for entire bar
- }
- }
- public int SelectedBand
- {
- get
- {
- return selectedBand;
- }
- set
- {
- SelectBand(value);
- }
- }
- public OutlookBar()
- {
- buttonHeight = ;
- selectedBand = ;
- selectedBandHeight = ;
- }
- public void Initialize()
- {
- // parent must exist!
- Parent.SizeChanged += new EventHandler(SizeChangedEvent);
- }
- public void AddBand(string caption, ContentPanel content)
- {
- content.outlookBar = this;
- int index = Controls.Count;
- BandTagInfo bti = new BandTagInfo(this, index);
- BandPanel bandPanel = new BandPanel(caption, content, bti);
- Controls.Add(bandPanel);
- UpdateBarInfo();
- RecalcLayout(bandPanel, index);
- }
- public void SelectBand(int index)
- {
- selectedBand = index;
- RedrawBands();
- }
- private void RedrawBands()
- {
- for (int i = ; i < Controls.Count; i++)
- {
- BandPanel bp = Controls[i] as BandPanel;
- RecalcLayout(bp, i);
- }
- }
- private void UpdateBarInfo()
- {
- selectedBandHeight = ClientRectangle.Height - (Controls.Count * buttonHeight);
- }
- private void RecalcLayout(BandPanel bandPanel, int index)
- {
- int vPos = (index <= selectedBand) ? buttonHeight * index : buttonHeight * index + selectedBandHeight;
- int height = selectedBand == index ? selectedBandHeight + buttonHeight : buttonHeight;
- // the band dimensions
- bandPanel.Location = new Point(, vPos);
- bandPanel.Size = new Size(ClientRectangle.Width, height);
- // the contained button dimensions
- bandPanel.Controls[].Location = new Point(, );
- bandPanel.Controls[].Size = new Size(ClientRectangle.Width, buttonHeight);
- // the contained content panel dimensions
- bandPanel.Controls[].Location = new Point(, buttonHeight);
- bandPanel.Controls[].Size = new Size(ClientRectangle.Width - , height - );
- }
- private void SizeChangedEvent(object sender, EventArgs e)
- {
- Size = new Size(Size.Width, ((Control)sender).ClientRectangle.Size.Height - 顶部位置偏移 - 底部位置偏移);
- UpdateBarInfo();
- RedrawBands();
- }
- }
- internal class BandPanel : Panel
- {
- public BandPanel(string caption, ContentPanel content, BandTagInfo bti)
- {
- BandButton bandButton = new BandButton(caption, bti);
- Controls.Add(bandButton);
- Controls.Add(content);
- }
- }
- internal class BandTagInfo
- {
- public OutlookBar outlookBar;
- public int index;
- public BandTagInfo(OutlookBar ob, int index)
- {
- outlookBar = ob;
- this.index = index;
- }
- }
- internal class BandButton : Button
- {
- private BandTagInfo bti;
- public BandButton(string caption, BandTagInfo bti)
- {
- Text = caption;
- FlatStyle = FlatStyle.Standard;
- Visible = true;
- this.bti = bti;
- Click += new EventHandler(SelectBand);
- }
- private void SelectBand(object sender, EventArgs e)
- {
- bti.outlookBar.SelectBand(bti.index);
- }
- }
- public abstract class ContentPanel : Panel
- {
- public OutlookBar outlookBar;
- public ContentPanel()
- {
- // initial state
- Visible = true;
- }
- }
- /// <summary>
- /// 主菜单项
- /// </summary>
- public class IconPanel : ContentPanel
- {
- protected int iconSpacing;
- protected int margin;
- public int IconSpacing
- {
- get
- {
- return iconSpacing;
- }
- }
- public int Margin
- {
- get
- {
- return margin;
- }
- }
- public IconPanel()
- {
- margin = ;
- iconSpacing = + + ; // icon height + text height + margin
- BackColor = Color.LightBlue;
- AutoScroll = true;
- }
- public PanelIcon AddIcon(string caption, Image image, EventHandler onClickEvent)
- { //添加小项按钮
- int index = Controls.Count / ; // two entries per icon
- PanelIcon result = new PanelIcon(this, image, index, onClickEvent);
- Controls.Add(result);
- Size sz = (image == null ? new Size(, ) : image.Size);
- //
- Label label = new Label();
- label.Text = caption;
- label.Visible = true;
- label.Location = new Point(, margin + sz.Height + index * iconSpacing);
- label.Size = new Size(Size.Width, );
- label.TextAlign = ContentAlignment.TopCenter;
- if (onClickEvent != null) label.Click += onClickEvent;
- label.Tag = result;
- Controls.Add(label);
- //
- return result;
- }
- }
- public class PanelIcon : PictureBox
- {
- public int index;
- public IconPanel iconPanel;
- private Color bckgColor;
- private bool mouseEnter;
- public int Index { get { return index; } }
- public PanelIcon(IconPanel parent, Image image, int index, EventHandler onClickEvent)
- { //新建按钮项
- this.index = index;
- this.iconPanel = parent;
- Image = image;
- Visible = true;
- Size sz = (image == null ? new Size(, ) : image.Size);
- Location = new Point(iconPanel.outlookBar.Size.Width / - sz.Width / ,
- iconPanel.Margin + index * iconPanel.IconSpacing);
- Size = sz;
- if (onClickEvent != null) Click += onClickEvent;
- Tag = this;
- MouseEnter += new EventHandler(OnMouseEnter);
- MouseLeave += new EventHandler(OnMouseLeave);
- MouseMove += new MouseEventHandler(OnMouseMove);
- bckgColor = iconPanel.BackColor;
- mouseEnter = false;
- }
- private void OnMouseMove(object sender, MouseEventArgs args)
- { //鼠标移动
- if ((args.X < Size.Width - ) &&
- (args.Y < Size.Width - ) &&
- (!mouseEnter))
- {
- BackColor = Color.LightCyan;
- BorderStyle = BorderStyle.FixedSingle;
- Location = Location - new Size(, );
- mouseEnter = true;
- }
- }
- private void OnMouseEnter(object sender, EventArgs e)
- {
- }
- private void OnMouseLeave(object sender, EventArgs e)
- { //鼠标离开
- if (!mouseEnter) return;
- //
- BackColor = bckgColor;
- BorderStyle = BorderStyle.None;
- Location = Location + new Size(, );
- mouseEnter = false;
- }
- }
- #region //调用的例子代码
- public class 调用的例子代码
- {
- private void loadLeftMenuBar(Form form)
- { //加载左侧菜单树
- //mnu_Main.Visible = false;
- object o = form.Controls.Find("mnu_Main", true), o2 = form.Controls.Find("sts_Main", true);
- if (o2 == null) o2 = form.Controls.Find("stb_Main", true);
- MenuStrip mnu_Main = (o == null ? null : o as MenuStrip);
- StatusStrip sts_Main = (o2 == null ? null : o2 as StatusStrip);
- string s = _iDefine.getRootPath() + "\\images\\";
- //初始化
- OutlookBar outlookBar = new OutlookBar();
- if (mnu_Main != null) outlookBar.顶部位置偏移 = (!mnu_Main.Visible ? : * (mnu_Main.Height + ));
- if (sts_Main != null) outlookBar.底部位置偏移 = sts_Main.Height + ;
- outlookBar.Location = new Point(, outlookBar.顶部位置偏移);
- outlookBar.Size = new Size(, form.ClientSize.Height - outlookBar.顶部位置偏移 - outlookBar.底部位置偏移);
- outlookBar.BorderStyle = BorderStyle.FixedSingle;
- form.Controls.Add(outlookBar);
- outlookBar.Initialize();
- //大块
- IconPanel iconPanel1 = new IconPanel();
- IconPanel iconPanel2 = new IconPanel();
- IconPanel iconPanel3 = new IconPanel();
- outlookBar.AddBand("Outlook Shortcuts", iconPanel1);
- outlookBar.AddBand("我的桌面", iconPanel2);
- outlookBar.AddBand("Other Shortcuts", iconPanel3);
- //小项
- iconPanel1.AddIcon("Outlook Today", Image.FromFile(s + "img1.ico"), new EventHandler(PanelEvent));
- iconPanel1.AddIcon("Calendar", Image.FromFile(s + "img2.ico"), new EventHandler(PanelEvent));
- iconPanel1.AddIcon("Contacts", Image.FromFile(s + "img3.ico"), new EventHandler(PanelEvent));
- iconPanel1.AddIcon("Tasks", Image.FromFile(s + "img4.ico"), new EventHandler(PanelEvent));
- iconPanel2.AddIcon("ABC", Image.FromFile(s + "img4.ico"), new EventHandler(PanelEvent));
- iconPanel3.AddIcon("DEFD", Image.FromFile(s + "img4.ico"), new EventHandler(PanelEvent));
- //选中第一项
- outlookBar.SelectBand();
- }
- public void PanelEvent(object sender, EventArgs e)
- {
- Control ctrl = (Control)sender;
- PanelIcon panelIcon = ctrl.Tag as PanelIcon;
- MessageBox.Show("#" + panelIcon.Index.ToString(), "Panel Event");
- }
- }
- #endregion
- }
Gs_Class中获取所有Delegate的代码:
- #region//取一个控件的事件托管清单:getComponentEventDelegates
- /// <summary>
- /// 取一个控件的事件托管清单,例如想判断一个GridView是否定义了PageIndexChanging事件
- /// 从CSDN搜来的:http://blog.csdn.net/zxkid/archive/2006/12/15/1444396.aspx
- /// </summary>
- /// <param name="component">组件对象实例</param>
- /// <param name="EventName">事件的名称,如:Click</param>
- /// <param name="EventHandlerTypeName">事件委托类型,如"ItemClickEventHander"</param>
- /// <returns></returns>
- public static Delegate[] getComponentEventDelegates(object component, string EventName, string EventHandlerTypeName)
- {
- //取控件的类型、属性列表、事件托管列表、头字段列表
- Type componentType = component.GetType();
- PropertyInfo eventsPropertyInfo = componentType.GetProperty("Events", BindingFlags.Instance | BindingFlags.NonPublic);
- EventHandlerList eventHanlderList = eventsPropertyInfo.GetValue(component, null) as EventHandlerList;
- FieldInfo HeadFieldInfo = eventHanlderList.GetType().GetField("head", BindingFlags.Instance | BindingFlags.NonPublic);
- object HeadObject = HeadFieldInfo.GetValue(eventHanlderList);
- //
- do
- {
- FieldInfo[] fieldInfoList = componentType.GetFields(BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic);
- foreach (FieldInfo fieldInfo in fieldInfoList)
- {
- object fieldValue = fieldInfo.GetValue(component);
- if (fieldValue != null)
- {
- Type fieldType = fieldValue.GetType();
- if (fieldType.Name == EventHandlerTypeName && (fieldValue as Delegate) != null)
- {
- return (fieldValue as Delegate).GetInvocationList();
- }
- else if (fieldType.Name == typeof(Object).Name)
- {
- if (fieldInfo.Name.IndexOf(EventName, StringComparison.OrdinalIgnoreCase) > -)
- {
- if (HeadObject != null)
- {
- Delegate delegateObject = eventHanlderList[fieldValue];
- if (delegateObject != null)
- return delegateObject.GetInvocationList();
- }
- }
- }
- }
- }
- componentType = componentType.BaseType;
- }
- while (componentType != null); //循环结束
- //
- if (HeadObject == null) return null; //没有
- object ListEntry = HeadObject;
- Type ListEntryType = ListEntry.GetType();
- FieldInfo handlerFieldInfo = ListEntryType.GetField("handler", BindingFlags.Instance | BindingFlags.NonPublic);
- FieldInfo keyFieldInfo = ListEntryType.GetField("key", BindingFlags.Instance | BindingFlags.NonPublic);
- FieldInfo nextFieldInfo = ListEntryType.GetField("next", BindingFlags.Instance | BindingFlags.NonPublic);
- while (ListEntry != null)
- {
- Delegate handler = handlerFieldInfo.GetValue(ListEntry) as Delegate;
- object key = keyFieldInfo.GetValue(ListEntry);
- ListEntry = nextFieldInfo.GetValue(ListEntry);
- if (handler != null && handler.GetType().Name == EventHandlerTypeName)
- return handler.GetInvocationList();
- }
- return null;
- }
- #endregion
转载请注明:海宏软件原创。
C#动态创建两个按钮,btn2复制btn1的Click事件,匿名委托的更多相关文章
- [转]android:动态创建多个按钮 及 批量设置监听
之前投机取巧,先创建好多个按钮,再根据需要的数量进行部分隐藏,不过还是逃不过呀. 这样根本无法批量地 findId,批量地 设置监听. 所以今天还是认认真真地研究回“动态创建按钮”,终于,通过不断尝试 ...
- Android开发之动态创建多个按钮
//获取屏幕大小,以合理设定 按钮 大小及位置 DisplayMetrics dm = new DisplayMetrics(); getWindowManager().getDefaultDispl ...
- JS: javascript 点击事件执行两次js问题 ,解决jquery绑定click事件出现点击一次执行两次问题
javascript 点击事件执行两次js问题 在JQuery中存在unbind()方法,先解绑再添加点击事件,解决方案为: $(".m-layout-setting").unbi ...
- WinForms中动态给treeView的节点添加ContextMenuStrip,并绑定Click事件
生成ContextMenuStrip var docMenu = new ContextMenuStrip(); ToolStripMenuItem deleteMenuItem = new Tool ...
- jquery利用appendTo动态创建元素
动态创建元素可以说是DOM中常做的事情,下面我来介绍在jquery中利用appendTo来动态创建元素,有需要的朋友可参考参考. 当HTML字符串是没有属性的元素是, 内部使用document.cre ...
- [C# 基础知识系列]专题五:当点击按钮时触发Click事件背后发生的事情 (转载)
当我们在点击窗口中的Button控件VS会帮我们自动生成一些代码,我们只需要在Click方法中写一些自己的代码就可以实现触发Click事件后我们Click方法中代码就会执行,然而我一直有一个疑问的—— ...
- 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 ...
- MFC动态创建按钮,并在按钮上实现位图的切换显示
动态创建按钮,并在按钮中添加位图,通过单击按钮显示不同的位图,可设置为显示按钮按下和弹起两种状态.只要判断a值从而输入不同的响应代码. 1.在头文件中添加: CButton *pBtn; 2.在初始化 ...
- MFC动态创建对话框中的按钮控件并创建其响应消息
转自:http://www.cnblogs.com/huhu0013/p/4626686.html 动态按钮(多个)的创建: 1.在类中声明并定义按钮控件的ID #define IDC_D_BTN 1 ...
随机推荐
- Android中怎么去除标题栏详解
怎么出去标题栏,我再另一个博客中亦有实例在这里再详细的解释一下,也让自己能更加巩固最简单也是小重要的东西. 这里有两种方法是比较好的... 第一种: 首先,在values中建一个theme.xml 代 ...
- ASP.NET MVC应用程序实现下载功能
ASP.NET MVC应用程序实现下载功能 上次Insus.NET有在MVC应用程序实现了上传文件的功能<MVC应用程序显示上传的图片> http://www.cnblogs.com/in ...
- 关于 MVCC 的基础
作为第一篇对 MVCC 的学习材料,以下内容翻译自 Wikipedia. 1. 什么是MVCC 1.1 基础概念 MVCC,Multi-Version Concurrency Control,多版本并 ...
- 排序算法的C#实现
8种主要排序算法的C#实现 新的一年到了,很多园友都辞职要去追求更好的工作环境,我也是其中一个,呵呵! 最近闲暇的时候我开始重温一些常用的算法.老早就买了<算法导论>,一直都没啃下去. ...
- iOS基础 - 多媒体
一.播放视频 iOS提供了叫做MPMoviePlayerController.MPMoviePlayerViewController的两个类,可以用来轻松播放视频 YouTobe就是用MPMovieP ...
- 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 ...
- 《12个有趣的C语言问答》评析2
<12个有趣的C语言问答>评析(2) 前文链接:http://www.cnblogs.com/pmer/p/3313913.html (没存盘,遭遇过热保护.至少4个问答的评论白写了.默哀 ...
- Object-c学习之路六(oc字符串文件读写)
// // main.m // NSString // // Created by WildCat on 13-7-25. // Copyright (c) 2013年 wildcat. All ri ...
- Asp.net QueryString批量插入和更新
public static string InsertOrUpdateQueryString(string[] keys, string[] values) { return InsertOrUpda ...
- Winform程序
故事的开端是这样的,小白是一个程序员,他确实也是一个小白,目前还在程序员发展的道路上,兢兢业业的小心求学. 有一天,小白接到一个任务,完成一个Winform程序,附加一个功能就是可以读IC卡. 小白终 ...