C#动态创建两个按钮,btn2复制btn1的Click事件,匿名委托

Posted 海宏软件

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

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

 

以上是关于C#动态创建两个按钮,btn2复制btn1的Click事件,匿名委托的主要内容,如果未能解决你的问题,请参考以下文章

单击按钮时的动画视图

两个按钮显示相同的 div。一键提供更多选项可见性

我的 WPF 按钮需要更改不同按钮的内容

自定义 CollectionViewCell 处理按钮按下

python_tkinter组件

CSS样式表怎么做