Avatar billede simsen Mester
21. januar 2007 - 19:32 Der er 15 kommentarer og
1 løsning

Menu struktur som træ fortsat fra 755838

Spørgsmål fortsat fra http://www.eksperten.dk/spm/755838

Håber du ser med dr_chaos.....

Jeg har forsøgt her til aften, at få det over i en database og så skrive den ekstra linie ind.

Den kender så ikke til Populate();  (no definition for Populate())

Mit problem er, når jeg trykker på en tekst nu, så laver den bare en ny træ struktur uden at folde ud eller lignende.

Min kode ser ud som følgende på nuværende tidspunkt:

Default.aspx
<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        &nbsp;Test af menustruktur<br />
        <br />
        <br />
        <br />
        <asp:TreeView ID="TreeView1" runat="server" OnSelectedNodeChanged="TreeView1_SelectedNodeChanged"
            ShowExpandCollapse="False">
            <Nodes>               
            </Nodes>
        </asp:TreeView>
        <br />
    </div>
    </form>
</body>
</html>

Default.aspx.cs
using System;
using System.Data;
using System.Configuration;
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;
using System.Data.OleDb;
using System.Xml;
using System.Xml.Xsl;
using System.Xml.XPath;
using System.IO;

public partial class _Default : System.Web.UI.Page
{   
    public string connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\\Inetpub\\wwwroot\\Test\\Menu\\menu.mdb;";

    protected void Page_Load(object sender, EventArgs e)
    {
        PopulateNodes();
    }

    void PopulateNodes()
    {
        DataTable messages = GetTreeViewData();
        DataView threads = GetThreads(messages);
        foreach (DataRowView row in threads)
        {
            TreeNode threadNode = new TreeNode();
            threadNode.Text = row["Subject"].ToString();
            threadNode.Value = row["MessageID"].ToString();
            TreeView1.Nodes.Add(threadNode);
            AddReplies(messages, threadNode);
        }
    }

    DataTable GetTreeViewData()
    {
        OleDbConnection con = new OleDbConnection(connectionString);
        OleDbDataAdapter dad = new
          OleDbDataAdapter("SELECT * FROM Discuss", con);
        DataTable dtbl = new DataTable();
        dad.Fill(dtbl);
        return dtbl;
    }

    DataView GetThreads(DataTable discuss)
    {
        DataView view = new DataView(discuss);
        view.RowFilter = "ParentID=0";
        return view;
    }

    void AddReplies(DataTable messages, TreeNode node)
    {
        DataView replies = GetReplies(messages, node.Value);
        foreach (DataRowView row in replies)
        {
            TreeNode replyNode = new TreeNode();
            replyNode.Text = row["Subject"].ToString();
            replyNode.Value = row["MessageID"].ToString();
            node.ChildNodes.Add(replyNode);
            AddReplies(messages, replyNode);
        }
    }

    DataView GetReplies(DataTable messages, string messageID)
    {
        DataView view = new DataView(messages);
        view.RowFilter = "ParentID=" + messageID;
        return view;
    }

    protected void TreeView1_SelectedNodeChanged(object sender, EventArgs e)
    {
        TreeView1.CollapseAll();
        ExpandNodes(TreeView1.SelectedNode.ValuePath);       
    }

    private void ExpandNodes(string valuepath)
    {
        string[] tmp = valuepath.Split('/');
        string tmpValuePath = string.Empty;
        foreach (string s in tmp)
        {
            tmpValuePath += s;
            TreeView1.FindNode(tmpValuePath).Populate();
            TreeView1.FindNode(tmpValuePath).Expand();
            tmpValuePath += "/";

        }
    }
}


Hvad skal jeg bruge istedet for:
TreeView1.FindNode(tmpValuePath).Populate();
så den laver det samme, som da jeg ikke hentede fra database?

mvh

simsen :-)
Avatar billede dr_chaos Nybegynder
22. januar 2007 - 07:45 #1
Hej igen.
jeg smider lige et eksempel på hvordan jeg gør det:
----------Treeview----------------------
<asp:TreeView ID="ProductsTree" OnTreeNodePopulate="ProductsTree_TreeNodePopulate" OnSelectedNodeChanged="ProductsTree_OnSelectedNodeChanged"
                    EnableClientScript="true"
                    PopulateNodesFromClient="true" runat="server" ShowLines="True">
                    <Nodes>
                        <asp:TreeNode PopulateOnDemand="True" Expanded="false" Text="Productgroups" Value="0">
                        </asp:TreeNode>
                    </Nodes>
                    <HoverNodeStyle Font-Underline="true" />
                    <SelectedNodeStyle BackColor="Gray" Font-Underline="true" />
                </asp:TreeView>
----------------

Jeg laver noder efterbehov på denne måde:
    protected void ProductsTree_TreeNodePopulate(object sender, TreeNodeEventArgs e)
    {
        //hvis der ikke er nogen child nodes til noden
        if (e.Node.ChildNodes.Count == 0)
        {
            switch (e.Node.Depth)
            {
                case 0:
                    {
                        p.getProductGroups(e.Node);
                        break;
                    }
                case 1:
                    {
                        //System.Diagnostics.Debug.WriteLine(ProductsTree.SelectedNode);
                        p.getProducts(e.Node);
                        break;
                    }
                default:
                    {
                        p.GetProductPackage(e.Node);
                        break;
                    }
            }
        }
    }


min expandnode ser ud på denne måde:

  string[] tmp = valuepath.Split('/');
        string tmpValuePath = string.Empty;
        for (int i = 0; i < tmp.Length;i++ )
        {

            if (i == 0)
                tmpValuePath = tmp[i];
            else
                tmpValuePath +="/"+ tmp[i];
         
                TreeNodeEventArgs e = new TreeNodeEventArgs(ProductsTree.FindNode(tmpValuePath));
                e.Node.ChildNodes.Clear();
                e.Node.PopulateOnDemand = false;
                ProductsTree_TreeNodePopulate(ProductsTree, e);
                ProductsTree.FindNode(tmpValuePath).Expand();
                ProductsTree.FindNode(tmpValuePath).Selected = true;
Avatar billede dr_chaos Nybegynder
22. januar 2007 - 07:45 #2
Jeg fik lige sagt lidt for meget med Populate()  :)
Avatar billede simsen Mester
22. januar 2007 - 07:58 #3
Nu gør du mig forvirret......

Altså du bruger ProductsTree_TreeNodePopulate(object sender, TreeNodeEventArgs e)
og expandnode istedet for mine  TreeView1_SelectedNodeChanged(object sender, EventArgs e) og string[] tmp = valuepath.Split('/');
        string tmpValuePath = string.Empty;
        foreach (string s in tmp)
        {
            tmpValuePath += s;
            TreeView1.FindNode(tmpValuePath).Populate();
            TreeView1.FindNode(tmpValuePath).Expand();
            tmpValuePath += "/";

        }

Skal jeg ikke igennem alt det andet (som jeg forøvrigt har taget fra msn egen siden) - og hvordan går du ind i en foreach - så du går igennem hele databasen?

mvh
simsen :-)
Avatar billede dr_chaos Nybegynder
22. januar 2007 - 08:17 #4
nej jeg bruger
ProductsTree_TreeNodePopulate istedet for populate.

På treeviewet har jeg angivet :
OnTreeNodePopulate="ProductsTree_TreeNodePopulate"

Det vil sige at jeg ikke generer hele træet på engang men kun de nødvendige dele.

Jeg sætter alle node som jeg tilføjer tik mit træ til PopulateOndemand=true.
Avatar billede simsen Mester
22. januar 2007 - 19:21 #5
Hej igen dr_chaos...

Håber du har stoooor tålmodighed med mig.....

For jeg kan ikke relatere det du forsøger, med det jeg gør....

Hvor henter du ind fra databasen af?

Du må også have noget i OnSelectedNodeChanged="ProductsTree_OnSelectedNodeChanged"?


Hvad har du stående i henholdsvis p.getProductGroups(e.Node); og p.getProducts(e.Node); og  p.GetProductPackage(e.Node); ?

mvh
simsen :-)
Avatar billede dr_chaos Nybegynder
23. januar 2007 - 08:03 #6
jeg har:
protected void ProductsTree_OnSelectedNodeChanged(object sender, EventArgs e)
    {
        ShowUserControls();
    }

private void ShowUserControls()
    {
        if (ProductsTree.SelectedNode != null)
        {
            switch (ProductsTree.SelectedNode.Depth)
            {
                case 0:
                    {
                        mvProdEdit.ActiveViewIndex = -1;
                        break;
                    }
                case 1:
                    {
                        mvProdEdit.SetActiveView(viewCatalog);
                        ucProductCatalog.LoadControlData(ProductsTree.SelectedValue);
                        break;
                    }
                default:
                    {
                        mvProdEdit.SetActiveView(viewProd);
                        ucShowProduct.LoadControlData(Convert.ToInt32(ProductsTree.SelectedValue));
                        break;
                    }
            }
        }
    }
Avatar billede dr_chaos Nybegynder
23. januar 2007 - 08:04 #7
Jeg har et multiview som jeg bruger til at vise nogle forskellige usercontrols.
Avatar billede dr_chaos Nybegynder
23. januar 2007 - 08:04 #8
Her henter jeg  niveau 1 i træet:
public void getProductGroups(TreeNode n)
    {
        //DataSet ds = new DataSet();
        using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultSqlConnection"].ConnectionString))
        {
            using (SqlCommand cmd = new SqlCommand())
            {
                try
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Connection = conn;
                    cmd.CommandText = "ph_GetProductGroups";
                    cmd.Connection.Open();
                    SqlDataReader dr = cmd.ExecuteReader();

                    while (dr.Read())
                    {
                        TreeNode t = new TreeNode(dr["produktgruppe"].ToString(), dr["produktgruppeid"].ToString());
                        if (Convert.ToInt32(dr["HasProducts"]) == 1)
                            t.PopulateOnDemand = true;
                        t.SelectAction = TreeNodeSelectAction.SelectExpand;
                        n.ChildNodes.Add(t);
                    }

                }
                catch (Exception e)
                {
                    System.Diagnostics.Debug.WriteLine(e);

                }
                finally
                {
                    cmd.Connection.Close();
                }
            }
        }

    }
Avatar billede dr_chaos Nybegynder
23. januar 2007 - 08:05 #9
Her henter jeg niveau 2 baseret på det valg brugeren har foretaget i træet:
public void getProducts(TreeNode n)
    {
        //DataSet ds = new DataSet();
        using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultSqlConnection"].ConnectionString))
        {
            using (SqlCommand cmd = new SqlCommand())
            {
                try
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Connection = conn;
                    cmd.CommandText = "ph_GetProducts";
                    cmd.Parameters.AddWithValue("productGroupID", n.Value);
                    cmd.Connection.Open();
                    SqlDataReader dr = cmd.ExecuteReader();

                    while (dr.Read())
                    {
                        TreeNode t = new TreeNode(dr["produkt"].ToString(), dr["produktnr"].ToString());
                        if (Convert.ToInt32(dr["HasProductPackage"]) == 1)
                            t.PopulateOnDemand = true;
                        t.SelectAction = TreeNodeSelectAction.Select;
                        n.ChildNodes.Add(t);
                    }

                }
                catch (Exception e)
                {
                    System.Diagnostics.Debug.WriteLine(e);

                }
                finally
                {
                    cmd.Connection.Close();
                }
            }
        }

    }
Avatar billede simsen Mester
24. januar 2007 - 14:28 #10
Hej igen dr_chaos

Jeg er rundt på gulvet og aner ikke hvordan og hvorledes. Jeg viser til sidst min kode:

Lige nu har jeg forsøgt med det du har givet af kode og der fremkommer følgende struktur, når jeg forsøger at køre det:

+ Productgroups
    +Hunde
      No value given for one or more parameters
    +Katte
      No value given for one or more parameters
    +Heste
      No value given for one or more parameters

Altså den kan ikke hente undermenu punkter ud..... Jeg tror (uden at vide det), at det er fordi, jeg ikke aner hvilken value, jeg skal give med ind som parameter i getProducts funktionen.

Jeg har også forsøgt at slette
<Nodes>
                <asp:TreeNode PopulateOnDemand="True" Expanded="false" Text="Productgroups" Value="0">
                </asp:TreeNode>
            </Nodes>
i aspx filen og så tilføje

t.Expanded = true; i getProductGroups funktionen - men så får jeg slet ikke vist noget. Hvordan undgår jeg den faste tekst "Productgroups" og henter bare fra databasen af?

Jeg har udkommenteret denne fra dig af - da jeg ikke aner, hvad du bruger den til?

//if (Convert.ToInt32(myReader["HasProductPackage"]) == 1)
            //    t.PopulateOnDemand = true;

Skal jeg bruge dine usercontrols til noget? Hvis ja - hvad?

og her er så koden:

Default.aspx
<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        &nbsp;Test af menustruktur<br />
        <br />
        <asp:TreeView ID="ProductsTree" OnTreeNodePopulate="ProductsTree_TreeNodePopulate" EnableClientScript="true" PopulateNodesFromClient="true" runat="server" ShowLines="True">
            <Nodes>
                <asp:TreeNode PopulateOnDemand="True" Expanded="false" Text="Productgroups" Value="0">
                </asp:TreeNode>
            </Nodes>
            <HoverNodeStyle Font-Underline="true" />
            <SelectedNodeStyle BackColor="Gray" Font-Underline="true" />
        </asp:TreeView>
    </div>
    </form>
</body>
</html>

Default.aspx.cs
using System;
using System.Data;
using System.Configuration;
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;
using System.Data.OleDb;
using System.Xml;
using System.Xml.Xsl;
using System.Xml.XPath;
using System.IO;

public partial class _Default : System.Web.UI.Page
{
    private OleDbConnection connection = null;
    public OleDbCommand command = null;
    public string connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\\Inetpub\\wwwroot\\Test\\Menu\\menu.mdb;";

    protected void Page_Load(object sender, EventArgs e)
    {
       
    }

    //Henter Niveau 1 ud
    public void getProductGroups(TreeNode n)
    {
        connection = new OleDbConnection(connectionString);
        command = new OleDbCommand();
        command.Connection = connection;
        connection.Open();

        DataTable myDataTable = new DataTable();
        myDataTable.Columns.Add(new DataColumn("CategoryID", Type.GetType("System.String")));
        myDataTable.Columns.Add(new DataColumn("ParentCategoryID", Type.GetType("System.String")));
        myDataTable.Columns.Add(new DataColumn("CategoryName", Type.GetType("System.String")));
        myDataTable.Columns.Add(new DataColumn("HasChilds", Type.GetType("System.String")));
        command.CommandText = "SELECT CategoryID, ParentCategoryID, CategoryName, HasChilds FROM CATEGORIES WHERE ParentCategoryID = 0";

        command.Parameters.Clear();

        OleDbDataReader myReader = command.ExecuteReader();

        while (myReader.Read())
        {
            TreeNode t = new TreeNode(myReader["CategoryName"].ToString(), myReader["CategoryID"].ToString());
            if (Convert.ToInt32(myReader["HasChilds"]) == 1)
                t.PopulateOnDemand = true;
            t.SelectAction = TreeNodeSelectAction.SelectExpand;
            t.Expanded = true;
            n.ChildNodes.Add(t);
        }       

    }

    //Henter Niveau 2 ud
    public void getProducts(TreeNode n)
    {
        connection = new OleDbConnection(connectionString);
        command = new OleDbCommand();
        command.Connection = connection;
        connection.Open();

        DataTable myDataTable = new DataTable();
        myDataTable.Columns.Add(new DataColumn("CategoryID", Type.GetType("System.String")));
        myDataTable.Columns.Add(new DataColumn("ParentCategoryID", Type.GetType("System.String")));
        myDataTable.Columns.Add(new DataColumn("CategoryName", Type.GetType("System.String")));
        myDataTable.Columns.Add(new DataColumn("HasChilds", Type.GetType("System.String")));
        command.CommandText = "SELECT CategoryID, ParentCategoryID, CategoryName, HasChilds FROM CATEGORIES WHERE ParentCategoryID = @n";

        command.Parameters.Clear();

        OleDbDataReader myReader = command.ExecuteReader();

        while (myReader.Read())
        {
            TreeNode t = new TreeNode(myReader["produkt"].ToString(), myReader["produktnr"].ToString());

            /// HVAD BRUGES DENNE TIL????
            //if (Convert.ToInt32(myReader["HasProductPackage"]) == 1)
            //    t.PopulateOnDemand = true;
            t.SelectAction = TreeNodeSelectAction.Select;
            n.ChildNodes.Add(t);
        } 
    }

   
    private void ExpandNodes(string valuepath)
    {
        string[] tmp = valuepath.Split('/');
        string tmpValuePath = string.Empty;
        for (int i = 0; i < tmp.Length; i++)
        {

            if (i == 0)
                tmpValuePath = tmp[i];
            else
                tmpValuePath += "/" + tmp[i];

            TreeNodeEventArgs e = new TreeNodeEventArgs(ProductsTree.FindNode(tmpValuePath));
            e.Node.ChildNodes.Clear();
            e.Node.PopulateOnDemand = false;
            ProductsTree_TreeNodePopulate(ProductsTree, e);
            ProductsTree.FindNode(tmpValuePath).Expand();
            ProductsTree.FindNode(tmpValuePath).Selected = true;
        }
    }

    protected void ProductsTree_TreeNodePopulate(object sender, TreeNodeEventArgs e)
    {
        //hvis der ikke er nogen child nodes til noden
        if (e.Node.ChildNodes.Count == 0)
        {
            switch (e.Node.Depth)
            {
                case 0:
                    {
                        getProductGroups(e.Node);
                        break;
                    }
                case 1:
                    {
                        getProducts(e.Node);
                        break;
                    }
                default:
                    {
                        getProductGroups(e.Node);
                        break;
                    }
            }
        }

    }
}


mvh

simsen :-)
Avatar billede dr_chaos Nybegynder
25. januar 2007 - 07:54 #11
prøv med
  //Henter Niveau 2 ud
        public void getProducts(TreeNode n)
        {
            connection = new System.Data.OleDb.OleDbConnection(connectionString);
            System.Data.OleDb.OleDbCommand command = new System.Data.OleDb.OleDbCommand();
            command.Connection = connection;
            connection.Open();

            DataTable myDataTable = new DataTable();
            myDataTable.Columns.Add(new DataColumn("CategoryID", Type.GetType("System.String")));
            myDataTable.Columns.Add(new DataColumn("ParentCategoryID", Type.GetType("System.String")));
            myDataTable.Columns.Add(new DataColumn("CategoryName", Type.GetType("System.String")));
            myDataTable.Columns.Add(new DataColumn("HasChilds", Type.GetType("System.String")));

            command.CommandText = "SELECT CategoryID, CategoryName FROM CATEGORIES WHERE ParentCategoryID = ?";
            command.Parameters.AddWithValue("@ParentCategoryID", n.Value);
            command.Parameters.Clear();

            OleDbDataReader myReader = command.ExecuteReader();

            while (myReader.Read())
            {
                TreeNode t = new TreeNode(myReader["CategoryName"].ToString(), myReader["CategoryID"].ToString());
                t.SelectAction = TreeNodeSelectAction.Select;
                n.ChildNodes.Add(t);
            }
        }
Avatar billede dr_chaos Nybegynder
25. januar 2007 - 07:55 #12
Jeg returnerer en værdi fra databasen om en node har childnodes.
Hvis den har det sætter jeg
t.PopulateOnDemand = true;

  /// HVAD BRUGES DENNE TIL????
            //if (Convert.ToInt32(myReader["HasProductPackage"]) == 1)
            //    t.PopulateOnDemand = true;
Avatar billede simsen Mester
25. januar 2007 - 09:35 #13
Jeg får fejlen "No value given for one or more required parameters."

Når jeg forsøger med run to curser, kan jeg se den kommer i følgende linie:

OleDbDataReader myReader = command.ExecuteReader();

Altså den i  public void getProducts(TreeNode n)

Mht.  //if (Convert.ToInt32(myReader["HasProductPackage"]) == 1)
            //    t.PopulateOnDemand = true;

Er det fordi, du har to tabeller til at hente fra? For troede at det var "HasProducts" der var den nemlig :-)

Hvad mht. at jeg ikke vil have teksten Productgroups - at den bare skal starte med at hente niveau1?

mvh
simsen :-)
Avatar billede simsen Mester
16. februar 2007 - 18:04 #14
dr_chaos

Smid også et svar her tak :-)

mvh
simsen :-)
Avatar billede dr_chaos Nybegynder
16. februar 2007 - 18:13 #15
svar :)
Avatar billede simsen Mester
16. februar 2007 - 18:30 #16
Og du får også dine meget velfortjente points igen igen :-)
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