2014-09-15 2 views
0

Я пробовал в течение недель о том, как петлить все предметы в моем 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; 
      } 

     } 

, как вы можете видеть больше подменю я имею больше кода я должен контролировать. Есть ли другой способ перебрать все элементы в главном меню. Я использую базу данных для контроля видимости всех пунктов меню. есть ли способ, который использует минимальный оператор цикла, а не цикл в подменю

+0

Могу ли я предложить, было бы здорово, если бы вы могли предоставить нам обзор ваших пунктов меню. Я имею в виду, что только иерархия ваших пунктов меню будет хорошей. –

+0

my heirarchy - menustrip -> submenu -> menuitem – Mandz

+0

Главное меню -> мастер -> мастер-работник. есть ли другой способ автоматического обнаружения всех элементов в моей основной полосе меню? – Mandz

ответ

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; 
      } 
     } 
    } 
} 

Учитывая вышесказанное, я полагаю, что вы делаете слишком много накладных расходов при определении видимости пунктов меню на значение

Update:

Просто, чтобы обеспечить ошибку приведения типа обыкновения происходить, вы можете проверить, является ли конвертируемой деталью, как:

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; 
       } 
      } 
     } 
    } 
+0

это может сработать. Я стараюсь играть с твоим предложением. Мне просто интересно, нет ли функции или встроенной функции C# для возврата всех «элементов меню» в «menustrip» независимо от иерархии? – Mandz

+1

Насколько я могу судить, о том, что я знаю, вы можете получить 'submenuitems'' DropDownItems' и в случае, если весь набор меню повторяется так же в 'MenuStrip', который также должен быть циклом. Поскольку .Net предоставляет перечислитель для выпадающих списков, они могут ожидать, что мы его получим :) –

+0

есть код для цикла, который может позволить вам использовать стиль массива для mainmenu или toplevel. образец, подобный этому mainmenu [2] -> подменю [3] -> элемент. – Mandz

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; 
       } 
      } 
    } 
+0

что такое linq? извините, если я задаю глупый вопрос. Я просто перешел из vb6, так что впервые услышал об linq.^_^ – Mandz

+0

umm попробуйте прочитать форму здесь http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b Это способ запуска запроса с объектов IEnumerable. – codebased

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]); 
} 

Не тестировал, но он должен работать следующим образом. Возможно, вам придется проверять типы, если вы используете seperators, так как я не помню, являются ли они отдельным элементом управления как ToolStripMenuItem. Просто измените аргумент recursiveLoop на Control и проверьте внутри typeof (item) и сравните его со всем, что вы используете, и делаете материал в соответствии с тем, что это такое, и ваши другие параметры