none
WinForm的Menu菜单问题 RRS feed

  • 问题

  • 问题描述:有一个Menu菜单。菜单里有一个一级菜单。然后需要在这个已有的一级菜单下动态生成二级菜单,同时还要注册相应生成二级菜单的Click事件。这个功能如何实现?我现在动态生成二级菜单已实现,但相应二级菜单的Click事件我不知道如何生成。因为二级菜单可能会有多个。希望大家能帮我想想解决方案,谢谢先:)
    zy
    2009年10月13日 7:04

答案

  • 你好!

    你在创建菜单时把菜单相关信息比如说 DataRow 存到 菜单的Tag 中,同时创建一个 Click 事件,在事件中通过 sender 得到 ToolStripMenuItem 大概好下

    private void toolStripMenuItem_Click(object sender, EventArgs e)
    {
        ToolStripMenuItem item = (ToolStripMenuItem)sender;
        DataRow row = (DataRow) item.Tag ;

        // 获取 row 的信息就能知道是那个菜单点击了
    }

    知识改变命运,奋斗成就人生!
    • 已标记为答案 张烨 2009年10月14日 6:13
    2009年10月13日 7:17
    版主
  • 你好!
         你可以这样:
         ToolStripItem tsi=ComPortSetting.DropDownItems.Add(sName);//会返回一个ToolStripItem实例
         然后:
         tsi.Click+=XXX      //订阅这个菜单项的Click事件
    周雪峰
    • 已标记为答案 张烨 2009年10月14日 6:14
    2009年10月13日 12:51
    版主

全部回复

  • 你好!

    你在创建菜单时把菜单相关信息比如说 DataRow 存到 菜单的Tag 中,同时创建一个 Click 事件,在事件中通过 sender 得到 ToolStripMenuItem 大概好下

    private void toolStripMenuItem_Click(object sender, EventArgs e)
    {
        ToolStripMenuItem item = (ToolStripMenuItem)sender;
        DataRow row = (DataRow) item.Tag ;

        // 获取 row 的信息就能知道是那个菜单点击了
    }

    知识改变命运,奋斗成就人生!
    • 已标记为答案 张烨 2009年10月14日 6:13
    2009年10月13日 7:17
    版主
  • 你好。
    按照我对问题的理解,我的解决方案如下:

    首先你已经具有一级菜单子项,你对每个子项的Click事件添加处理程序,在处理程序中 动态创建新的 ToolStripMenuItem 对象,并添加到产生Click事件的 1级菜单项的子项集合中。利用DropDownItems属性。
    同时在你创建新的 ToolStripMenuItem 对象时,就可以注册新的Click事件处理。

    可能说得比较含糊,我提供代码如下:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;

    namespace Problem1_2009_10_13
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();

                foreach (ToolStripMenuItem item in 菜单ToolStripMenuItem.DropDownItems)
                {
                    //对1级子菜单项的Click事件添加处理程序
                    item.Click += item_Click;
                }
            }

            void item_Click(object sender, EventArgs e)
            {
                ToolStripMenuItem source = sender as ToolStripMenuItem;

                label1.Text = "Click:" + source.Name;

                ToolStripMenuItem level2Item = null;
                for (int i = 0; i < 5; i++)
                {
                    //在处理程序中动态生成5个新的2级子菜单项,并添加到source(即产生事件的1级子菜单项)
                    level2Item = new ToolStripMenuItem(string.Format("{0} - item{1}",source.Text,i));

                    level2Item.Click += item_Click; //这里就可以捕捉你想要的2级子菜单项的Click事件

                    source.DropDownItems.Add(level2Item);
                }
            }
        }
    }


    以下是WinForm设计器生成的代码: 复制以下代码就可以产生对应的窗体。

    namespace Problem1_2009_10_13
    {
        partial class Form1
        {
            /// <summary>
            /// Required designer variable.
            /// </summary>
            private System.ComponentModel.IContainer components = null;

            /// <summary>
            /// Clean up any resources being used.
            /// </summary>
            /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
            protected override void Dispose(bool disposing)
            {
                if (disposing && (components != null))
                {
                    components.Dispose();
                }
                base.Dispose(disposing);
            }

            #region Windows Form Designer generated code

            /// <summary>
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// </summary>
            private void InitializeComponent()
            {
                this.menuStrip1 = new System.Windows.Forms.MenuStrip();
                this.菜单ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
                this.item1ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
                this.item2ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
                this.item3ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
                this.label1 = new System.Windows.Forms.Label();
                this.menuStrip1.SuspendLayout();
                this.SuspendLayout();
                //
                // menuStrip1
                //
                this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
                this.菜单ToolStripMenuItem});
                this.menuStrip1.Location = new System.Drawing.Point(0, 0);
                this.menuStrip1.Name = "menuStrip1";
                this.menuStrip1.Size = new System.Drawing.Size(744, 24);
                this.menuStrip1.TabIndex = 0;
                this.menuStrip1.Text = "menuStrip1";
                //
                // 菜单ToolStripMenuItem
                //
                this.菜单ToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
                this.item1ToolStripMenuItem,
                this.item2ToolStripMenuItem,
                this.item3ToolStripMenuItem});
                this.菜单ToolStripMenuItem.Name = "菜单ToolStripMenuItem";
                this.菜单ToolStripMenuItem.Size = new System.Drawing.Size(41, 20);
                this.菜单ToolStripMenuItem.Text = "菜单";
                //
                // item1ToolStripMenuItem
                //
                this.item1ToolStripMenuItem.Name = "item1ToolStripMenuItem";
                this.item1ToolStripMenuItem.Size = new System.Drawing.Size(100, 22);
                this.item1ToolStripMenuItem.Text = "Item1";
                //
                // item2ToolStripMenuItem
                //
                this.item2ToolStripMenuItem.Name = "item2ToolStripMenuItem";
                this.item2ToolStripMenuItem.Size = new System.Drawing.Size(100, 22);
                this.item2ToolStripMenuItem.Text = "Item2";
                //
                // item3ToolStripMenuItem
                //
                this.item3ToolStripMenuItem.Name = "item3ToolStripMenuItem";
                this.item3ToolStripMenuItem.Size = new System.Drawing.Size(100, 22);
                this.item3ToolStripMenuItem.Text = "Item3";
                //
                // label1
                //
                this.label1.AutoSize = true;
                this.label1.Location = new System.Drawing.Point(46, 130);
                this.label1.Name = "label1";
                this.label1.Size = new System.Drawing.Size(41, 12);
                this.label1.TabIndex = 1;
                this.label1.Text = "label1";
                //
                // Form1
                //
                this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
                this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
                this.ClientSize = new System.Drawing.Size(744, 429);
                this.Controls.Add(this.label1);
                this.Controls.Add(this.menuStrip1);
                this.MainMenuStrip = this.menuStrip1;
                this.Name = "Form1";
                this.Text = "Form1";
                this.menuStrip1.ResumeLayout(false);
                this.menuStrip1.PerformLayout();
                this.ResumeLayout(false);
                this.PerformLayout();

            }

            #endregion

            private System.Windows.Forms.MenuStrip menuStrip1;
            private System.Windows.Forms.ToolStripMenuItem 菜单ToolStripMenuItem;
            private System.Windows.Forms.ToolStripMenuItem item1ToolStripMenuItem;
            private System.Windows.Forms.ToolStripMenuItem item2ToolStripMenuItem;
            private System.Windows.Forms.ToolStripMenuItem item3ToolStripMenuItem;
            private System.Windows.Forms.Label label1;
        }
    }

    2009年10月13日 7:34
  • 在设计页面点击完一级菜单不就可以直接添加二级菜单了吗?!
    难道我理解错了。
    Do My Best
    2009年10月13日 7:51
  • 谢谢zwjKL的回复。我提供下我的代码:
    private void frmIQCDataInput_Load(object sender, EventArgs e)
            {
                string[] sPortName = SerialPort.GetPortNames();

                if(sPortName.Length < 1)
                {
                    MessageBox.Show("本机没有COM端口!!");
                }
                else
                {
                    foreach(string sName in sPortName)
                    {
                        ComPortSetting.DropDownItems.Add(sName);
                       
                        SelectComPort.DropDownItems.Add(sName);
                    }
                }
            }

    上面的代码就是产生第三级菜单的代码。这里如何动态加上菜单的点击事件?


    zy
    2009年10月13日 8:11
  • 不管你有多少级,事件代码只有一个。
    知识改变命运,奋斗成就人生!
    2009年10月13日 8:13
    版主
  • 这个我知道,问题是如何创建这个事件以供动态生成的菜单使用?这是我现在的难点。
    zy
    2009年10月13日 8:14
  • 你好。

    请问你所说的“创建这个事件”具体是什么意思?
    事件的处理程序是否预先已经决定好?
    假如是的话,以下代码可以解决。
     foreach(string sName in sPortName)
                    {
                        ComPortSetting.DropDownItems.Add(sName);
                        ComPortSetting.Click += YourEventHandler1;
                        
                        SelectComPort.DropDownItems.Add(sName);
                        SelectComPort.Click += YourEventHandler2;
                    }

    还是你希望整个动态创建子菜单项的过程,都把事件处理方法作为参数传入到frmIQCDataInput_Load方法中?
    2009年10月13日 9:11
  • 你好!
         你可以这样:
         ToolStripItem tsi=ComPortSetting.DropDownItems.Add(sName);//会返回一个ToolStripItem实例
         然后:
         tsi.Click+=XXX      //订阅这个菜单项的Click事件
    周雪峰
    • 已标记为答案 张烨 2009年10月14日 6:14
    2009年10月13日 12:51
    版主