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 顶部位置偏移 = 0; //zch,20161226 public int 底部位置偏移 = 0; 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 = 25; selectedBand = 0; selectedBandHeight = 0; } 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 = 0; 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(0, vPos); bandPanel.Size = new Size(ClientRectangle.Width, height); // the contained button dimensions bandPanel.Controls[0].Location = new Point(0, 0); bandPanel.Controls[0].Size = new Size(ClientRectangle.Width, buttonHeight); // the contained content panel dimensions bandPanel.Controls[1].Location = new Point(0, buttonHeight); bandPanel.Controls[1].Size = new Size(ClientRectangle.Width - 2, height - 8); } 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 = 10; iconSpacing = 32 + 15 + 10; // icon height + text height + margin BackColor = Color.LightBlue; AutoScroll = true; } public PanelIcon AddIcon(string caption, Image image, EventHandler onClickEvent) { //添加小项按钮 int index = Controls.Count / 2; // two entries per icon PanelIcon result = new PanelIcon(this, image, index, onClickEvent); Controls.Add(result); Size sz = (image == null ? new Size(0, 0) : image.Size); // Label label = new Label(); label.Text = caption; label.Visible = true; label.Location = new Point(0, margin + sz.Height + index * iconSpacing); label.Size = new Size(Size.Width, 15); 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(0, 0) : image.Size); Location = new Point(iconPanel.outlookBar.Size.Width / 2 - sz.Width / 2, 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 - 2) && (args.Y < Size.Width - 2) && (!mouseEnter)) { BackColor = Color.LightCyan; BorderStyle = BorderStyle.FixedSingle; Location = Location - new Size(1, 1); 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(1, 1); 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 ? 0 : 1 * (mnu_Main.Height + 0)); if (sts_Main != null) outlookBar.底部位置偏移 = sts_Main.Height + 2; outlookBar.Location = new Point(0, outlookBar.顶部位置偏移); outlookBar.Size = new Size(150, 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(0); } 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) > -1) { 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
转载请注明:海宏软件原创。