如何循环菜单条级别中的所有子菜单项

时间:2014-09-15 03:59:14

标签: c# database loops menustrip

我几周来一直试图如何循环SubMenu MenuStrip上的所有项目。我的问题是,如果我添加一个新的SubMenu,我必须输入一个代码再循环它来控制我的项目。基本上我正在循环我的SubMenu只是为了控制我的项目。我想要的是循环MenuStrip级别的所有项目而不是子菜单级别

这是我的层次结构。 enter image description here

这是我的代码

public void startUpRoleControl()
    {
        loadRoleControl();
        disableAllToolStripItems();

        bool varmasterDropItem = false;
        bool varservicesDropItem = false;
        bool varreportsDropItem = false;
        bool varmaintenanceDropItem = false;
        bool varuseroptionsDropItem = false;

        if (dtDBRoleControl.Rows.Count > 0)
        {
            foreach(DataRow drmaster in dtDBRoleControl.Rows)
            {
                foreach (ToolStripItem masterDropItem in masterToolStripMenuItem.DropDownItems) // use to disable sub items of mastermenu
                {
                    if (masterDropItem.Tag != null)
                    {
                        if (masterDropItem.Tag.ToString() == drmaster["rprevformname"].ToString() && Convert.ToInt32(drmaster["rprevview"]) == 1)
                        {
                            masterDropItem.Visible = true;
                            varmasterDropItem = true;
                            break;
                        }
                    }
                }
            }
            foreach (DataRow drservices in dtDBRoleControl.Rows)
            {
                foreach (ToolStripItem servicesDropItem in servicesToolStripMenuItem.DropDownItems) // use to disable sub items of mastermenu
                {
                    if (servicesDropItem.Tag != null)
                    {
                        if (servicesDropItem.Tag.ToString() == drservices["rprevformname"].ToString() && Convert.ToInt32(drservices["rprevview"]) == 1)
                        {
                            servicesDropItem.Visible = true;
                            varservicesDropItem = true;
                            break;
                        }
                    }
                }
            }
            foreach (DataRow drreports in dtDBRoleControl.Rows)
            {
                foreach (ToolStripItem reportsDropItem in reportsToolStripMenuItem.DropDownItems) // use to disable sub items of mastermenu
                {
                    if (reportsDropItem.Tag != null)
                    {
                        if (reportsDropItem.Tag.ToString() == drreports["rprevformname"].ToString() && Convert.ToInt32(drreports["rprevview"]) == 1)
                        {
                            reportsDropItem.Visible = true;
                            varreportsDropItem=true;
                            break;
                        }
                    }
                }
            }
            foreach (DataRow druseroptions in dtDBRoleControl.Rows)
            {
                foreach (ToolStripItem useroptionsDropItem in reportsToolStripMenuItem.DropDownItems) // use to disable sub items of mastermenu
                {
                    if (useroptionsDropItem.Tag != null)
                    {
                        if (useroptionsDropItem.Tag.ToString() == druseroptions["rprevformname"].ToString() && Convert.ToInt32(druseroptions["rprevview"]) == 1)
                        {
                            useroptionsDropItem.Visible = true;
                            varuseroptionsDropItem = true;
                            break;
                        }
                    }
                }
            }
            foreach (DataRow drmaintenance in dtDBRoleControl.Rows)
            {
                foreach (ToolStripItem maintenanceDropItem in maintenanceToolStripMenuItem.DropDownItems) // use to disable sub items of mastermenu
                {
                    if (maintenanceDropItem.Tag != null)
                    {
                        if (maintenanceDropItem.Tag.ToString() == drmaintenance["rprevformname"].ToString() && Convert.ToInt32(drmaintenance["rprevview"]) == 1)
                        {
                            maintenanceDropItem.Visible = true;
                            varmaintenanceDropItem = true;
                            break;
                        }
                    }
                }
            }



            if (varmasterDropItem == true) // shows master item if there is a item in master that are visible
            {
                masterToolStripMenuItem.Visible = true;
            }
            if (varservicesDropItem == true)// shows services item if there is a item in services that are visible
            {
               servicesToolStripMenuItem.Visible = true;
            }
            if (varreportsDropItem == true)// shows services item if there is a item in services that are visible
            {
                reportsToolStripMenuItem.Visible = true;
            }
            if (varmaintenanceDropItem == true)// shows services item if there is a item in services that are visible
            {
                maintenanceToolStripMenuItem.Visible = true;
            }
            if (varuseroptionsDropItem == true)// shows services item if there is a item in services that are visible
            {
                userOptionsToolStripMenuItem.Visible = true;
            }

        }

你可以看到更多的子菜单我有更多的代码我必须控制。有没有其他方法可以循环主菜单中的所有项目。我正在使用数据库来控制所有菜单项的可见性。有没有办法使用最小的循环语句而不是每个子菜单循环

3 个答案:

答案 0 :(得分:1)

好的,这就是我可以根据您的图片/示例尝试的内容 (这会遍历所有菜单和子菜单项,然后设置其可见性 - 在Visual Studio 2010中测试):

public void startUpRoleControl()
{
    loadRoleControl();
    disableAllToolStripItems();

    if (dtDBRoleControl.Rows.Count > 0)
    {               
        for (int i = 0; i < menuStrip1.Items.Count; i++ ) //menuStrip1 is the main menu strip which holds the menu items.
        {
            foreach(DataRow drmaster in dtDBRoleControl.Rows)
            {
                ProcessDropDown(menuStrip1.Items[i], drmaster["rprevformname"].ToString(), Convert.ToInt32(drmaster["rprevview"]) );
            }
        }
    }
}

private void ProcessDropDown(ToolStripItem item, string rprevformname, int rprevview)
{
    ToolStripMenuItem menuItem = (ToolStripMenuItem)item; //Type casting from ToolStripItem to ToolStripMenuItem
    if (!menuItem.HasDropDownItems)
        return;
    else
    {
        foreach (ToolStripMenuItem val in menuItem.DropDownItems)
        {
            if (val.HasDropDownItems)
                ProcessDropDown(val, rprevformname, rprevview);
            if (val.Tag != null && val.Tag.ToString() == rprevformname, && rprevview == 1)
            {
                val.Visible = false;
                menuItem.Visible = false;
            }
        }
    }
}

考虑到上述情况,我建议您在决定值的菜单项可见性时花费太多开销

<强>更新

为了确保不会发生类型转换的错误,您可以检查该项是否可转换,如:

    private void ProcessDropDown(ToolStripItem item)
    {
        ToolStripMenuItem menuItem = item as ToolStripMenuItem; //Type casting from ToolStripItem to ToolStripMenuItem
        if (menuItem == null) 
            return;

        if (!menuItem.HasDropDownItems)
            return;
        else
        {
            foreach (var val in menuItem.DropDownItems)
            {
                ToolStripMenuItem menuTool = val as ToolStripMenuItem;

                if (menuTool == null) 
                    continue;

                if (menuTool.HasDropDownItems)
                    ProcessDropDown(menuTool);
                if (menuTool.Tag != null && menuTool.Tag.ToString() == "nagaraj")
                {
                    menuTool.Text = false;
                    menuItem.Visible = false;
                }
           }
        }
    }

答案 1 :(得分:0)

没有人能给你一个确切的答案。但是,这里是你与Linq一起玩的主角。

public class AccessRight
    {

        public string FormName { get; set; }
        public int CanView { get; set; }
    }

    public void ApplySecurity() 
    {
        // --- 
        if (dtDBRoleControl.Rows.Count > 0)
        {
            // first loop through your database rows. 
            // create a small POCO to perform actions.
            List<AccessRight> accessRights = new List<AccessRight>();
            foreach(var drmaster in dtDBRoleControl.Rows){
                var access = new AccessRight() { FormName = drmaster["rprevformname"].ToString(), CanView = Convert.ToInt32(drmaster["rprevview"]) };
                accessRights.Add(access);
            }

            // close your database here...




            // now for each menu call a method as given below

            PerformActionOnMenu(masterToolStripMenuItem, accessRights);
            PerformActionOnMenu(servicesToolStripMenuItem, accessRights);
            PerformActionOnMenu(reportsToolStripMenuItem, accessRights);
            PerformActionOnMenu(maintenanceToolStripMenuItem, accessRights);


        }
    }

    private void PerformActionOnMenu(ToolStripMenuItem menuItem , List<AccessRight> accessRights)
    {
        var result = from item in menuItem.DropDownItems
                         where item.Tag != null && item.Tag.ToString()
                         join x in accessRights on x.FormName.Equals( item.Tag) 
                         select new { DropDownItem = item, Access = x};

            if ( result != null && result.Count() > 0 ) 
            {   
                menuItem.Visible = true;        
                foreach(var r in results ){
                     r.DropDownItem.Visible = true;
                }
            }
    }

答案 2 :(得分:0)

将条带更改为您调用MenuStrip控件的任何内容。

private void startLoop()
{
    for(int a = 0; a< strip.Items.Count;a++)
        recursiveLoop(strip.Items[a]);
}

private void recursiveLoop(ToolStripMenuItem item)
{
    //DO YOUR LOGIC HERE
    item.Visible = true;
    //
    for(int a = 0; a< item.Items.Count;a++)
        recusiveLoop(item.Items[a]);
}

没有测试它,但它应该像这样工作。如果您使用分隔符,则可能需要检查类型,因为我不记得它们是否是作为ToolStripMenuItem的单独控件。只需将recursiveLoop参数更改为Control并检入内部typeof(item)并将其与您使用的所有内容进行比较,并根据其内容和其他参数进行操作