我几周来一直试图如何循环SubMenu
MenuStrip
上的所有项目。我的问题是,如果我添加一个新的SubMenu
,我必须输入一个代码再循环它来控制我的项目。基本上我正在循环我的SubMenu
只是为了控制我的项目。我想要的是循环MenuStrip
级别的所有项目而不是子菜单级别
这是我的层次结构。
这是我的代码
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;
}
}
你可以看到更多的子菜单我有更多的代码我必须控制。有没有其他方法可以循环主菜单中的所有项目。我正在使用数据库来控制所有菜单项的可见性。有没有办法使用最小的循环语句而不是每个子菜单循环
答案 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)并将其与您使用的所有内容进行比较,并根据其内容和其他参数进行操作