zoukankan      html  css  js  c++  java
  • 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

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

  • 相关阅读:
    设计一个数据结构,包含两个函数,1.插入一个数字,2.获得中数
    数状数组
    25匹马,每次能5匹一起跑,选出最快的3匹
    禁止ImageCapture自动启动
    SublimeText Videos Notes
    10G个64bit整数,找出中位数
    python初步要点II
    python初步要点
    找出丢失的数字
    nice & renice
  • 原文地址:https://www.cnblogs.com/HaiHong/p/6224416.html
Copyright © 2011-2022 走看看