Avatar billede innercitydk Nybegynder
31. oktober 2007 - 08:01 Der er 4 kommentarer og
1 løsning

Rekursiv metode til opbygning af en menustruktur

Hej Eksperter. Jeg er ved at stirre mig blind på et problem jeg har og håber der er nogen der kan gennemskue det.

Jeg har en menu der dynamisk bliver opbygget via data i en access db. Indtil videre har jeg kun brugt to levels i menuen. Menuen skal nu laves mere dynamisk og jeg skal bruge en rekursiv metode til at opbygge den da der kan være x antal levels under hver node.

Jeg starter med at hente alle menuitems i databasen hvorefter jeg laver en list med alle top level items. Hver af disse kan så have subitems der hver især igen kan have subitems osv osv. Det er her problemet opstår. Hvordan laver jeg en rekursiv metode der kan klare dette?

Pt. ser min kode ud som herunder. Den tager kun højde for 2 levels, men skal altså moddes så den kan have x antal levels under hver hoved item. (koden bruges i et website, men det jeg efterspørger er jo kodet i C# så det burde ikke betyde noget)

if (!Page.IsPostBack)
        {
            controller = new Controller();
            ArrayList menuItems = controller.GetFrontendMenu();
            ArrayList subMenuItems = controller.GetFrontendSubMenu();
            skmMenu.MenuItem oMitem1;
            skmMenu.MenuItem oMsubItem1;           
            foreach (MenuItem oMtmp in menuItems)
            {
                if (oMtmp.isactive)
                {
                    oMitem1 = new skmMenu.MenuItem("<font style='color:White;'>"+oMtmp.linktext+"</font>&nbsp;&nbsp;", oMtmp.link);
                    foreach (Submenu oStmp in subMenuItems)
                    {
                        if (oStmp._oMid == oMtmp.id)
                        {
                            if (oStmp._oSisactive)
                            {
                                oMsubItem1 = new skmMenu.MenuItem(oStmp._oSlinktext, oStmp._oSlink);
                                oMitem1.SubItems.Add(oMsubItem1);
                            }
                        }
                    }
                    Menu1.Items.Add(oMitem1);
                }
            }
            Menu1.Cursor = skmMenu.MouseCursor.Pointer;
            Menu1.HighlightTopMenu = false;
            Menu1.Opacity = "50";
        }

Venlig hilsen

Nicki
Avatar billede innercitydk Nybegynder
31. oktober 2007 - 08:13 #1
Obs jeg har ændret i databasen så det enkelte menuitem ser således ud:

private int _mid;  --> Autonummerering.
private int _mpid;  --> Parent node (mid)
private int _mindex;  --> Placering i forhold til de andre items.
private bool _mitemstatic;  --> Bruges til at bedømme hvorvidt det specifikke item må slettes
private string _mlinktext;  --> Teksten i menuen
private string _mlink;  --> Link til side
private bool _misactive;  --> Bruges til at aktivere/deaktivere et item
Avatar billede innercitydk Nybegynder
31. oktober 2007 - 08:14 #2
ArrayList menuItems = controller.GetFrontendMenu(); <-- Bruger kun denne!

ArrayList subMenuItems = controller.GetFrontendSubMenu(); <-- Bruges ikke mere!!
Avatar billede neoman Novice
31. oktober 2007 - 09:11 #3
Du kan formentligt få lidt inspiration her http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.treeview.nodes(vs.80).aspx
hvor du kan se, hvordan man rekursivt gennemløber bestående nodes i et treeview.
Med lidt ændringer skal du nok bare have fat i en liste af de childnodes som tilhører den node du står på, og så adde dem.
Avatar billede innercitydk Nybegynder
31. oktober 2007 - 13:19 #4
Den havde jeg allerede kigget på den side.. Leder mere efter en dude der kan tage min kode og omforme den så den virker!
Avatar billede innercitydk Nybegynder
02. november 2007 - 08:09 #5
Løste selv problemet:

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class usercontrols_frontendsitemenu : System.Web.UI.UserControl
{
    private Controller controller;
    private ArrayList menuItems;

    protected void Page_Load(object sender, EventArgs e)
    {
        controller = new Controller();
        menuItems = controller.GetFrontendSiteMenu();
        if (!Page.IsPostBack)
        {
            skmMenu.MenuItem oMitem1;
            int oHasNodes;
            foreach (SiteMenuItem oMtmp in menuItems)
            {
                oHasNodes = 0;
                if (!oMtmp.misactive && oMtmp.mpid == 0)
                {
                    oMitem1 = new skmMenu.MenuItem("<font style='color:White;'>" + oMtmp.mlinktext + "</font>&nbsp;&nbsp;", oMtmp.mlink);
                    oHasNodes = HasNodes(oMtmp);
                    if (oHasNodes > 0)
                        GetNodes(oMtmp, oMitem1);
                    Menu1.Items.Add(oMitem1);
                }
            }
            Menu1.Cursor = skmMenu.MouseCursor.Pointer;
            Menu1.HighlightTopMenu = false;
            Menu1.Opacity = "50";
        }
    }

    private void GetNodes(SiteMenuItem oMtmp, skmMenu.MenuItem oMitem1)
    {
        int oHasNodes;
        skmMenu.MenuItem oMitem2;
        foreach (SiteMenuItem oMtmp2 in menuItems)
        {
            oHasNodes = 0;
            if (!oMtmp2.misactive)
            {
                if (oMtmp2.mpid == oMtmp.mid)
                {                   
                    oHasNodes = HasNodes(oMtmp2);
                    if (oHasNodes > 0)
                    {
                        oMitem2 = new skmMenu.MenuItem("<font style='color:White;'>" + oMtmp2.mlinktext + "</font>&nbsp;&nbsp;", oMtmp2.mlink);
                        GetNodes(oMtmp2, oMitem2);
                        oMitem1.SubItems.Add(oMitem2);
                    } 
                    else
                        oMitem1.SubItems.Add(new skmMenu.MenuItem("<font style='color:White;'>" + oMtmp2.mlinktext + "</font>&nbsp;&nbsp;", oMtmp2.mlink));
                }
            }
        }
    }

    private int HasNodes(SiteMenuItem oMtmp)
    {
        int oTmp = 0;
        foreach (SiteMenuItem oMtmp2 in menuItems)
        {
            if (!oMtmp2.misactive)
            {
                if (oMtmp2.mpid == oMtmp.mid)
                {
                    oTmp++;
                }
            }
        }
        return oTmp;
    }
}
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester