Monday, March 26, 2012

Treeview inside update panel adds nodes when expanded/collapsed

Hi all,

I have something weird going on with a page with 3 treeview controls. I have them set to be expanded by default, but when I click on the collapse (or expand) image on any of the 3 treeviews, a new node is added in my second treeview with repeating data, ie:

TreeView1

1.01.11.22.02.1

TreeView2

3.03.13.2

Now, if I click on 2.0 to collapse it, a new node in TreeView2 will appear, same as 3.0. If I expand 2.0 again, or collapse another node, 3.0 is added again to TreeView2. I'm getting the data from a database table.

Here is the page behind:

protected void Page_Load(object sender, EventArgs e) {if (!Page.IsPostBack) PopulateRootLevel(); PopulateRootLevel_OD(); PopulateRootLevel_RO(); }//TreeView 1//private void PopulateRootLevel() { SqlConnection objConn =new SqlConnection("Data Source=##;Initial Catalog=##;Integrated Security=True"); SqlCommand objCommand =new SqlCommand("select *,(select count(*) FROM ccForum_Posts WHERE parentid=sc.id) childnodecount FROM ccForum_Posts sc where parentID='0' AND status='ac' AND sticky='1' ORDER BY DateTime", objConn); SqlDataAdapter da =new SqlDataAdapter(objCommand); DataTable dt =new DataTable(); da.Fill(dt); PopulateNodes(dt, TreeView1.Nodes); }private void PopulateSubLevel(int parentid, TreeNode parentNode) { SqlConnection objConn =new SqlConnection("Data Source=##;Initial Catalog=##;Integrated Security=True"); SqlCommand objCommand =new SqlCommand("select *,(select count(*) FROM ccForum_Posts WHERE parentid=sc.id) childnodecount FROM ccForum_Posts sc where parentID=@dotnet.itags.org.parentID AND status='ac' ORDER BY sticky, DateTime", objConn); objCommand.Parameters.Add("@dotnet.itags.org.parentID", SqlDbType.Int).Value = parentid; SqlDataAdapter da =new SqlDataAdapter(objCommand); DataTable dt =new DataTable(); da.Fill(dt); PopulateNodes(dt, parentNode.ChildNodes); }protected void TreeView1_TreeNodePopulate(object sender, TreeNodeEventArgs e) { PopulateSubLevel(Int32.Parse(e.Node.Value), e.Node); }private void PopulateNodes(DataTable dt, TreeNodeCollection nodes) {foreach (DataRow drin dt.Rows) { TreeNode tn =new TreeNode(); tn.ToolTip = dr["Message"].ToString(); tn.Text = dr["subject"].ToString() +" - <span style=font-size:xx-small;> by " + dr["Author"].ToString() +" on " + dr["DateTime"].ToString() +"</span>"; tn.Value = dr["id"].ToString(); tn.NavigateUrl ="~/Post.aspx?MID=" + dr["id"].ToString() +"&PID=" + dr["PostID"].ToString(); nodes.Add(tn);//If node has child nodes, then enable on-demand populating tn.PopulateOnDemand = ((int)(dr["childnodecount"]) > 0); } }protected void Button_Command(Object sender, CommandEventArgs e) {switch (e.CommandName) {case"Expand": TreeView1.ExpandAll();break;case"Collapse": TreeView1.CollapseAll();break;default:// Do nothing.break; } }//TreeView 2//private void PopulateRootLevel_OD() { SqlConnection objConn_OD =new SqlConnection("Data Source=##;Initial Catalog=##;Integrated Security=True"); SqlCommand objCommand_OD =new SqlCommand("select *,(select count(*) FROM ccForum_Posts WHERE parentid=sc.id) childnodecount FROM ccForum_Posts sc where parentID='0' AND status='ac' AND sticky='2' ORDER BY DateTime", objConn_OD); SqlDataAdapter da_OD =new SqlDataAdapter(objCommand_OD); DataTable dt_OD =new DataTable(); da_OD.Fill(dt_OD); PopulateNodes_OD(dt_OD, TreeView2.Nodes); }private void PopulateSubLevel_OD(int parentid, TreeNode parentNode) { SqlConnection objConn =new SqlConnection("Data Source=##;Initial Catalog=##;Integrated Security=True"); SqlCommand objCommand =new SqlCommand("select *,(select count(*) FROM ccForum_Posts WHERE parentid=sc.id) childnodecount FROM ccForum_Posts sc where parentID=@dotnet.itags.org.parentID AND status='ac' ORDER BY sticky, DateTime", objConn); objCommand.Parameters.Add("@dotnet.itags.org.parentID", SqlDbType.Int).Value = parentid; SqlDataAdapter da =new SqlDataAdapter(objCommand); DataTable dt =new DataTable(); da.Fill(dt); PopulateNodes_OD(dt, parentNode.ChildNodes); }protected void TreeView2_TreeNodePopulate(object sender, TreeNodeEventArgs e) { PopulateSubLevel_OD(Int32.Parse(e.Node.Value), e.Node); }private void PopulateNodes_OD(DataTable dt, TreeNodeCollection nodes) {foreach (DataRow drin dt.Rows) { TreeNode tn =new TreeNode(); tn.ToolTip = dr["Message"].ToString(); tn.Text = dr["subject"].ToString() +" - <span style=font-size:xx-small;> by " + dr["Author"].ToString() +" on " + dr["DateTime"].ToString() +"</span>"; tn.Value = dr["id"].ToString(); tn.NavigateUrl ="~/Post.aspx?MID=" + dr["id"].ToString() +"&PID=" + dr["PostID"].ToString(); nodes.Add(tn);//If node has child nodes, then enable on-demand populating tn.PopulateOnDemand = ((int)(dr["childnodecount"]) > 0); } }protected void Button_Command_OD(Object sender, CommandEventArgs e) {switch (e.CommandName) {case"Expand": TreeView2.ExpandAll();break;case"Collapse": TreeView2.CollapseAll();break;default:// Do nothing.break; } }//TreeView 3//private void PopulateRootLevel_RO() { SqlConnection objConn =new SqlConnection("Data Source=##;Initial Catalog=##;Integrated Security=True"); SqlCommand objCommand =new SqlCommand("select *,(select count(*) FROM ccForum_Posts WHERE parentid=sc.id) childnodecount FROM ccForum_Posts sc where parentID='0' AND status='ro' ORDER BY sticky, DateTime", objConn); SqlDataAdapter da =new SqlDataAdapter(objCommand); DataTable dt =new DataTable(); da.Fill(dt); PopulateNodes_RO(dt, TreeView3.Nodes); }private void PopulateSubLevel_RO(int parentid, TreeNode parentNode) { SqlConnection objConn =new SqlConnection("Data Source=##;Initial Catalog=##;Integrated Security=True"); SqlCommand objCommand =new SqlCommand("select *,(select count(*) FROM ccForum_Posts WHERE parentid=sc.id) childnodecount FROM ccForum_Posts sc where parentID=@dotnet.itags.org.parentID ORDER BY DateTime", objConn); objCommand.Parameters.Add("@dotnet.itags.org.parentID", SqlDbType.Int).Value = parentid; SqlDataAdapter da =new SqlDataAdapter(objCommand); DataTable dt =new DataTable(); da.Fill(dt); PopulateNodes_RO(dt, parentNode.ChildNodes); }protected void TreeView3_TreeNodePopulate(object sender, TreeNodeEventArgs e) { PopulateSubLevel_RO(Int32.Parse(e.Node.Value), e.Node); }private void PopulateNodes_RO(DataTable dt, TreeNodeCollection nodes) {foreach (DataRow drin dt.Rows) { TreeNode tn =new TreeNode(); tn.ToolTip = dr["Message"].ToString(); tn.Text = dr["subject"].ToString() +" - <span style=font-size:xx-small;> by " + dr["Author"].ToString() +" on " + dr["DateTime"].ToString() +"</span>"; tn.Value = dr["id"].ToString(); tn.NavigateUrl ="~/Post.aspx?MID=" + dr["id"].ToString() +"&PID=" + dr["PostID"].ToString(); nodes.Add(tn);//If node has child nodes, then enable on-demand populating tn.PopulateOnDemand = ((int)(dr["childnodecount"]) > 0); } }protected void Button_Command_RO(Object sender, CommandEventArgs e) {switch (e.CommandName) {case"Expand": TreeView3.ExpandAll();break;case"Collapse": TreeView3.CollapseAll();break;default:// Do nothing.break; } }

And here is the control:

<%@dotnet.itags.org. Control Language="C#" AutoEventWireup="true" CodeFile="ct_forum_2.ascx.cs" Inherits="ccforum_ct_forum" %><asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <h3>TreeView1 - <asp:ImageButton ID="ExpandButton" runat="server" ImageUrl="~/images/expandall.jpg" CommandName="Expand" OnCommand="Button_Command" AlternateText="Open All Conversations" />   <asp:ImageButton ID="CollapseButton" runat="server" ImageUrl="~/images/collapseall.jpg" CommandName="Collapse" OnCommand="Button_Command" AlternateText="Close All Conversations" /></h3> <asp:TreeView ID="TreeView1" ExpandDepth="10" runat="server" OnTreeNodePopulate="TreeView1_TreeNodePopulate" ImageSet="Inbox" EnableClientScript="False" Width="100%" BackColor="White" BorderColor="#404040" LineImagesFolder="~/TreeLineImages" ShowLines="True" > <ParentNodeStyle Font-Bold="False" /> <HoverNodeStyle Font-Underline="True" /> <SelectedNodeStyle Font-Underline="True" HorizontalPadding="0px" VerticalPadding="0px" BackColor="#404040" /> <NodeStyle Font-Names="Verdana" Font-Size="8pt" ForeColor="Black" HorizontalPadding="5px" NodeSpacing="0px" VerticalPadding="0px" /> </asp:TreeView><br /> <h3>TreeView2 - <asp:ImageButton ID="ImageButton1" runat="server" ImageUrl="~/images/expandall.jpg" CommandName="Expand" OnCommand="Button_Command_OD" AlternateText="Open All Conversations" />   <asp:ImageButton ID="ImageButton2" runat="server" ImageUrl="~/images/collapseall.jpg" CommandName="Collapse" OnCommand="Button_Command_OD" AlternateText="Close All Conversations" /></h3> <asp:TreeView ID="TreeView2" ExpandDepth="10" runat="server" OnTreeNodePopulate="TreeView2_TreeNodePopulate" ImageSet="Inbox" EnableClientScript="False" Width="100%" BackColor="White" BorderColor="#404040" LineImagesFolder="~/TreeLineImages" ShowLines="True" > <ParentNodeStyle Font-Bold="False" /> <HoverNodeStyle Font-Underline="True" /> <SelectedNodeStyle Font-Underline="True" HorizontalPadding="0px" VerticalPadding="0px" BackColor="#404040" /> <NodeStyle Font-Names="Verdana" Font-Size="8pt" ForeColor="Black" HorizontalPadding="5px" NodeSpacing="0px" VerticalPadding="0px" /> </asp:TreeView> <br /> <h3>TreeView3 - <asp:ImageButton ID="ImageButton3" runat="server" ImageUrl="~/images/expandall.jpg" CommandName="Expand" OnCommand="Button_Command_RO" AlternateText="Open All Conversations" />   <asp:ImageButton ID="ImageButton4" runat="server" ImageUrl="~/images/collapseall.jpg" CommandName="Collapse" OnCommand="Button_Command_RO" AlternateText="Close All Conversations" /></h3> <asp:TreeView ID="TreeView3" ExpandDepth="10" runat="server" OnTreeNodePopulate="TreeView3_TreeNodePopulate" ImageSet="Inbox" EnableClientScript="False" Width="100%" BackColor="White" BorderColor="#404040" LineImagesFolder="~/TreeLineImages" ShowLines="True" > <ParentNodeStyle Font-Bold="False" /> <HoverNodeStyle Font-Underline="True" /> <SelectedNodeStyle Font-Underline="True" HorizontalPadding="0px" VerticalPadding="0px" BackColor="#404040" /> <NodeStyle Font-Names="Verdana" Font-Size="8pt" ForeColor="Black" HorizontalPadding="5px" NodeSpacing="0px" VerticalPadding="0px" /> </asp:TreeView> </ContentTemplate></asp:UpdatePanel>

Any help will be truly appreciated.

Jose

Well, I hate to answer my own posts, but I guess stepping out of the office gave me a fresh set of eyes. My problem lied in the IsPostBack property:

protected void Page_Load(object sender, EventArgs e) {if (!Page.IsPostBack) PopulateRootLevel(); PopulateRootLevel_OD(); PopulateRootLevel_RO(); }

It should be:

if (!Page.IsPostBack) { PopulateRootLevel(); PopulateRootLevel_OD(); PopulateRootLevel_RO(); }
Hope it helps someone.

No comments:

Post a Comment