Cian
Cian

Reputation: 81

Why do my nodes duplicate when I select a child node?

My second ASP.NET question. Still going through the ropes...

So every time I click on a child node the root nodes collapse and both the roots and children duplicate. I have absolutely no idea why. This appears to happen across all browsers I am currently working with (IE, Chrome and Firefox).

The children's node action is select. When I click on a node the table in the adjacent div updates with information garnered from an SQL database.

The site is quite rough... Trying to learn ASP.NET and Webforms internals before making it look pretty.

Image one - I have opened a root node and am about to select a child.

enter image description here

Image two - I have selected a child node. The root nodes have collapsed (?) and have duplicated.

enter image description here

Image three - I reopen a root node and the children have all duplicated. enter image description here

The background C# code:

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace LocalTest
{
    public partial class WebForm1 : System.Web.UI.Page
    {

        //Setup connection string.
        SqlConnection conn;
        SqlDataReader reader = null;


        protected void Page_Load(object sender, EventArgs e)
        {
            //Table1.Visible = false;
            conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnection"].ConnectionString);

            //Initial treeview setup.
            TreeInit();

            //Initial table setup
            TableInit();

            try
            {
                //Open connection and set up reader.
                conn.Open();

                SqlCommand cmd = new SqlCommand("select BatchNumber, Area from tblBatch;", conn);

                reader = cmd.ExecuteReader();

                while(reader.Read())
                {
                    //Fill up each nodes with respective Batch Numbers.
                    if(reader["Area"].ToString().Equals("N"))
                    {
                        TreeNode aNode = new TreeNode(reader["BatchNumber"].ToString());
                        aNode.SelectAction = TreeNodeSelectAction.Select;
                        TreeView1.Nodes[0].ChildNodes.Add(aNode);
                    }
                    else
                    {
                        TreeNode aNode = new TreeNode(reader["BatchNumber"].ToString());
                        aNode.SelectAction = TreeNodeSelectAction.Select;
                        TreeView1.Nodes[1].ChildNodes.Add(aNode);
                    }
                }

                conn.Close();

                TreeView1.CollapseAll();

            }
            catch (Exception er)
            {

            }

        }

        protected void Chart1_Load(object sender, EventArgs e)
        {

        }

        protected void Chart1_Load1(object sender, EventArgs e)
        {

        }

        protected void OnSelectNode(object sender, EventArgs e)
        {
            //Response.Write(TreeView1.SelectedNode.Text);
            string batchNumber = TreeView1.SelectedNode.Text;
            Response.Write(batchNumber);//Debugging

            conn.Open();
            SqlCommand cmd = new SqlCommand("select * from tblTemp where BatchId = (select Id from tblBatch where BatchNumber = " + batchNumber + ")", conn);
            reader = cmd.ExecuteReader();


            while(reader.Read())
            {
                TableRow aRow = new TableRow();

                for (int i = 0; i < 5; i++)
                {
                    TableCell aCell = new TableCell();
                    aCell.Text = reader[i].ToString();
                    aRow.Cells.Add(aCell);                    
                }
                Table1.Rows.Add(aRow);
            }

            conn.Close();

            //Table1.Visible = true;

        }

        protected void TableInit()
        {
            TableRow headerRow = new TableRow();
            TableCell headerCell1 = new TableCell();
            TableCell headerCell2 = new TableCell();
            TableCell headerCell3 = new TableCell();
            TableCell headerCell4 = new TableCell();
            TableCell headerCell5 = new TableCell();

            headerCell1.Text = "Id";
            headerCell2.Text = "BatchId";
            headerCell3.Text = "Temp1";
            headerCell4.Text = "Temp2";
            headerCell5.Text = "Seq No.";

            headerRow.Cells.Add(headerCell1);
            headerRow.Cells.Add(headerCell2);
            headerRow.Cells.Add(headerCell3);
            headerRow.Cells.Add(headerCell4);
            headerRow.Cells.Add(headerCell5);

            Table1.Rows.Add(headerRow);
        }

        protected void TreeInit()
        {
            //Create nodes.
            TreeNode nordonNode = new TreeNode("Nordon");
            TreeNode bobyNode = new TreeNode("Boby");

            //Set select action to expand. Not doing this resulting in duplication of nodes.
            nordonNode.SelectAction = TreeNodeSelectAction.Expand;
            bobyNode.SelectAction = TreeNodeSelectAction.Expand;

            //Add nodes to treeview.
            TreeView1.Nodes.Add(nordonNode);
            TreeView1.Nodes.Add(bobyNode);
        }


    }
}

The WebForm HTML/ASP:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="LocalTest.WebForm1" %>

<%@ Register assembly="System.Web.DataVisualization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" namespace="System.Web.UI.DataVisualization.Charting" tagprefix="asp" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Cast Records</title>
    <link rel="stylesheet" type="text/css" href="CSS/StyleSheet.css"/>
</head>
<body>
    <form id="form1" runat="server">
    <div>

        <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:MyConnection %>" ></asp:SqlDataSource>
        <!--SelectCommand="SELECT * FROM [People]"-->
    </div>
    <!-- header for the page -->
    <div id="header">

    </div>

    <!-- tree view div -->
    <div id="treeViewDiv">
        <asp:TreeView ID="TreeView1" runat="server" Height="571px" ShowLines="True" Width="135px" OnSelectedNodeChanged="OnSelectNode" style="position: relative">
        </asp:TreeView>
    </div>

    <!-- table div -->
    <div id="tableDiv">
        <asp:Table ID="Table1" runat="server" Height="96px" Width="459px" style="z-index: 1; left: 343px; top: 238px; position: relative; height: 96px; width: 459px" BackColor="#99CCFF" BorderColor="#FFFF99" BorderStyle="Solid" BorderWidth="2px" GridLines="Both">
        </asp:Table>
    </div>
    </form>
</body>
</html>

The Stylesheet:

body {
}

#header{
    width: 100%;
    height:100px;
    background-color: #66FFFF;

}

#treeViewDiv{
    float:left;
    width: 30%;
    height: 500px;
    background-color: #ff6a00;
    overflow: auto;
}

#tableDiv{    
    float: right;
    width:70%;
    height:500px;
    background-color: #00ff21;
}

EDIT: Lifecycle and (!IsPostBack). Gotcha! Thanks very much guys. I encased the code with (!IsPostBack) and it helped in some places and caused issues elsewhere. I know where to go now. Thanks for the responses.

Upvotes: 0

Views: 602

Answers (2)

MABVT
MABVT

Reputation: 1360

considering your description the code executed Page_Load is executed multiple times, i.e. creation of the root nodes, appending the subitems from the database to root at index 0 and 1, i.e. duplicate entries!

I'm not a 100% sure, BUT the invocation of SelectedNodeChanged not only triggers your OnSelectNode, but also causes a Post_Back to the server causing Page_Load to be executed again!

See this the following line of this ( unfortunately ) german page: http://www.aspheute.com/artikel/20000922.htm

Die Anweisungen innerhalb dieser Eventroutine werden bei jedem Seitenaufruf, bzw. PostBack ausgeführt.

Translation: "The statements within this event routine ( = Page_Load ) are executed on each page request or PostBack."

This means, that on each event, that will cause asp.net functionality to be executed on the SAVED STATE OF THE PAGE ON THE SERVER, will cause a postback and thus Page_Load to be executed again.

Consequently you might consider to move the initialization/creation code into an if-block like this:

if(!Page.IsPostBack)
{ // This page is loaded the fist time, i.e. no postback event due to selections
// Code...
}

I hope this will fix your problem and help.

Greetings, Marc

Upvotes: 1

CyberDude
CyberDude

Reputation: 8959

You might want to wrap your initialization code from Page_Load in if (!IsPostback) {}

And also read a bit about a page's life cycle and the viewstate to understand why the duplication occurs.

Upvotes: 3

Related Questions