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 ...
随机推荐
- Metro UI 界面完全解析 (转载)
Metro在微软的内部开发名称为“ typography-based design language”(基于排版的设计语言).它最早出现在微软电子百科全书95,此后微软又有许多知名产品使用了Metro ...
- ibatis提示Unable to load embedded resource from assembly "Entity.Ce_SQL.xml,Entity".
原本以为是xml文件配置错误,尝试无果,最终原因未将xml文件的生成操作选择为嵌入的资源.很无语!
- Operating System 概述和学习图
Operating System 概述和学习图 大神绕道,鄙人初入 OS . 一.想知OS,先知计算机系统概述 #图解 #基本指令和中断周期 #直接内存存取(Direct Memory Access, ...
- 领域模型中分散的事务如何集中统一处理(C#解决方案)
领域模型中分散的事务如何集中统一处理(C#解决方案) 开篇 什么是事务,事务的应用场景 做项目时,经常会遇到一些需求,比如注册用户时,要求同时存入用户的基本信息和初始化该用户的帐户,如果在这两个环 ...
- Dogs[HDU2822]
Dogs Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submissio ...
- baidu 200兆SVN代码服务器
转 今天心情好,给各位免费呈上200兆SVN代码服务器一枚,不谢! 开篇先给大家讲个我自己的故事,几个月前在网上接了个小软件开发的私活,平日上班时间也比较忙,就中午一会儿休息时间能抽出来倒腾着去做 ...
- dyld binding test
========================================================================= a.c ---------------------- ...
- 企业架构研究总结(43)——企业架构与建模之ArchiMate详述(下)
2.7 关系模型元素 企业架构模型包括了各种概念元素以及他们之间的关系,这其中的概念元素已经在前面几节中进行了阐述,而这些概念元素之间的关系则是本节的叙述重点.虽然ArchiMate中具有种类繁多的概 ...
- 运用Unity结合PolicyInjection实现拦截器
运用Unity结合PolicyInjection实现拦截器[结合操作日志实例] 上一篇文章我们通过Unity自身Unity.InterceptionExtension.IInterceptionBeh ...
- iOS AVCaptureDevice的一些动西
http://blog.sina.com.cn/s/blog_78a55c9f01011apc.html