Autor Beitrag
TheoFontane
Hält's aus hier
Beiträge: 2

Win XP, Win 7
C# (VS 2010), VB.Net (VS 2010)
BeitragVerfasst: Di 29.03.11 17:28 
Hallo,

ich möchte mein MenuStrip-Element dynamisch zur Laufzeit aus einer XML-Datei laden, die beliebig tief geschachtelt ist. Aktuell werden die Elemente im MenuStrip zwar hierarchisch, dafür aber (teilweise falsch geschachtelt) ca. viermal angelegt - ich muss noch einen Denkfehler in der Rekursion haben...

Hier meine zwei Funktionen, wie sie bisher aussehen:
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
//Wird einmalig aufgerufen
      public static bool retrieveMenuStrip(ref MenuStrip menuStrip)
      {
         try
         {
            if (menuStrip == nullreturn false;
            menuStrip.Items.Clear();                      
            XDocument xDoc = XDocument.Load(menueListConfigurationFile);            
            XName b = standardXMLNameSpace + "Menu";
            var menuQuery = from menuItem in xDoc.Element(b).DescendantsAndSelf()
                            select menuItem;
            if (menuQuery.Count().Equals(0)) throw new Exception("Menu is not defined. Please check the definition file.");
            ToolStripMenuItem newItem = new ToolStripMenuItem("DUMMY");
            //Lookup the XML recursively and retrieve the menu-structure 
            if (!getMenuStructure(menuQuery.ElementAt(0), ref newItem)) return false;
            menuStrip.Items.Add(newItem);            

            return true;
         }
         catch (Exception ex)
         {
            throw new Exception("retrieveMenuStrip", ex);
         }
      }

//Stellt die Rekursion dar
      private static bool getMenuStructure(XElement menuElement, ref ToolStripMenuItem menuStripItem)
      {
         try
         {                    
            foreach (XElement subElement in menuElement.Descendants())
            {
               ToolStripMenuItem newStripItem = new ToolStripMenuItem();    
               if (subElement.Name.LocalName.Equals("MenuElement"))
               {
                  //add sub-ordered menuItem       
                  newStripItem.Name = subElement.Attribute("MenuName").Value;
                  newStripItem.Tag = "SUBMENU";
                  newStripItem.Text = subElement.Name.LocalName;
                  if (!getMenuStructure(subElement, ref newStripItem)) return false;                  
               }
               else if (subElement.Name.LocalName.Equals("Form"))
               {
                  //add link to a form
                  newStripItem.Name = subElement.Attribute("FormName").Value;
                  newStripItem.DisplayStyle = ToolStripItemDisplayStyle.Text;
                  newStripItem.Tag = "FORM";
                  newStripItem.Text = subElement.Attribute("Title").Value;
               }
               else
               {
                  continue;
               }
               menuStripItem.DropDown.Items.Add(newStripItem);   
            }
            return true;
         }
         catch (Exception ex)
         {
            throw new Exception("getMenuStructure", ex);
         }
      }


Nur der Vollständigkeit halber hier auch die zugehörige XML-Datei. Zur Erklärung: Ein "MenuElement" besitzt immer ein anderes "MenuElement" als Kind oder ein "Form"-Element.
ausblenden XML-Daten
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
<?xml version="1.0" encoding="utf-8" ?>
<Menu>
   <MenuElement MenuName="Start">
      <Form FormName="TracesForm" Title="Traces"/>
      <MenuElement MenuName="SubMenue1">
         <MenuElement MenuName="SubSubMenue1">
            <Form FormName="AlarmsForm" Title="Alarms"/>
         </MenuElement>
         <MenuElement MenuName="SubSubMenue2"></MenuElement>
      </MenuElement>
      <MenuElement MenuName="Edit">
         <MenuElement MenuName="First">            
         </MenuElement>
         <MenuElement MenuName="Second">            
         </MenuElement>
         <MenuElement MenuName="Third">
            <Form FormName="TestForm" Title="Test 1"/>
            <Form FormName="TestGridForm" Title="Grid 1"/>
            <Form FormName="TestGridForm" Title="Grid 2"/>
         </MenuElement>
      </MenuElement>
   </MenuItem>   
</Menu>


Fällt einem von euch auf, was ich in der Rekursion falsch gemacht haben könnte?

Danke im Voraus für alle Hinweise und Ideen!
Theo
TheoFontane Threadstarter
Hält's aus hier
Beiträge: 2

Win XP, Win 7
C# (VS 2010), VB.Net (VS 2010)
BeitragVerfasst: Mi 30.03.11 11:18 
Für den Fall das jemand dieses Forum und diesen Thread in einer Suchmaschine finden sollte: Ich habe einen guten Lösungsansatz gefunden und auf mein Problem adaptieren könnten.
Quelle des Lösungsansatzes: seattlesoftware.word...ts-in-c/#comment-166


Hier der überarbeitete Code für die rekursive Funktion.
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
private static void getMenuStructure(XElement menuElement, ref ToolStripMenuItem menuStripItem)
      {
         try
         {
            if (!menuElement.HasElements)
            {               
               if (menuElement.Name.LocalName.Equals("Form"))
               {                  
                  addFormItemToMenuStripItem(menuElement, menuStripItem);//add link to a form
               }
               else if (menuElement.Name.LocalName.Equals("MenuElement"))
               {                            
                  addMenuItemToMenuStripItem(menuElement, menuStripItem);//add sub-ordered menuItem     
               }
            }
            else
            {
               ToolStripMenuItem newStripItem = addMenuItemToMenuStripItem(menuElement, menuStripItem);               
               foreach (XElement subElement in menuElement.Elements())
               {
                  getMenuStructure(subElement, ref newStripItem);
               }               
            }
         }
         catch (Exception ex)
         {
            throw new Exception("getMenuStructure", ex);
         }
      }

      private static ToolStripMenuItem addFormItemToMenuStripItem(XElement menuElement, ToolStripMenuItem menuStripItem)
      {
         ToolStripMenuItem newStripItem = new ToolStripMenuItem();
         newStripItem.Name = menuElement.Attribute("FormName").Value;
         newStripItem.DisplayStyle = ToolStripItemDisplayStyle.Text;
         newStripItem.Tag = "FORM";
         newStripItem.Text = menuElement.Attribute("Title").Value;
         menuStripItem.DropDown.Items.Add(newStripItem);
         return newStripItem;
      }

      private static ToolStripMenuItem addMenuItemToMenuStripItem(XElement menuElement, ToolStripMenuItem menuStripItem)
      {
         ToolStripMenuItem newStripItem = new ToolStripMenuItem();
         newStripItem.Name = menuElement.Attribute("MenuName").Value;
         newStripItem.Tag = "SUBMENU";
         newStripItem.Text = newStripItem.Name;
         menuStripItem.DropDown.Items.Add(newStripItem);
         return newStripItem;
      }


Vielen Dank für die rege Beteiligung - ich werde mal nach einem anderen Forum Ausschau halten...