Dynamically adding DropDownList - if I set ID also, I lose PostBack EventHandler

D

DotNetJunky

I have built a control that runs an on-line help system. Depending on the
category you selected via dropdownlist, it goes out and gets the child
subcategories, and if there are any, adds a new dropdownlist to the screen
for selection. This continues until there are no children, and then it
checks for a help article list based on that last selection and displays
actual articles for display.

Adding the controls and getting everything displaying has worked fine so
far. the problem is when the user goes back and changes a past dropdown, i
need to account for what happens to the successive dropdowns related to that
parent.

What i decide was just to disable previously selected dropdowns, each time a
new one is added, and then add a link to "start-over" basically.

Unfortunately, i cant even loop through the dynamically added dropdownlists
on the page because if i set an ID property when they are added, i lose my
postback event!

Can anyone explain to me what is going on with that or any alternatives?

I even tried adding an "id" attribute to the dropdownlists, and then my
postback handler works again but i cannot do a page.findcontrol() on that
attribute value, because it really isn't the "ID" of it, it doesn't find it.

Thanks in advance.

- DotNetJunky
 
J

Jeffrey Palermo, MCAD.Net

Look at the javascript being run when your drop down initiates a
postback. One of the arguments in the unique id of the control. The
last part of the unique id must be the same as the id of the control.

Can you post the code you are using to create the control, add the
control to the page, set the id of the control and subscribe to the
event of the control?

With dynamically added controls, there are some issues that may arise
if the control isn't in the same index of the Controls collection. on
the postback. Add dynamic controls on the Init phase of the page
lifecycle. It's also a good practice to add the control to the page's
Controls collection before setting additional properties.

If you can post a stripped-down code sample that exibits the undesired
behavior, I'd be glad to assist you further.

Best regards,
Jeffrey Palermo
Blog: http://www.jeffreypalermo.com
 
D

DotNetJunky

I am storing the categories posted back from the dropdowns into an arrayList
and then ViewStating the arrayList. On PostBack i check that arrayList and
re-run the routine which builds the dropDowns and adds them to the page with
their event handlers.

I am adding them manually to the control hierarchy, by simply adding a new
asp:table cell and then adding the control to it.

attached is sample test code (thrown together in an hour just to see if my
idea for this thing would even work). let me know what you think i may be
able to do to fix this. SOme of the code is remmed out just so it works for
you if you set it up to test. thanks,

DNJ

========================================================================

using System;
using System.Collections;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace Testing
{
/// <summary>
/// Summary description for TestDD.
/// </summary>
public class TestDD : System.Web.UI.Page
{
protected System.Web.UI.WebControls.Table tblCategory;
protected System.Web.UI.WebControls.Label lblArticleDate;
protected System.Web.UI.WebControls.Label lblArticleTitle;
protected System.Web.UI.WebControls.Label lblArticleContent;
protected System.Web.UI.WebControls.DropDownList ddList1;
protected System.Web.UI.WebControls.LinkButton lbRestart;
protected System.Web.UI.HtmlControls.HtmlForm Form1;

private void Page_Load(object sender, System.EventArgs e)
{
// Put user code to initialize the page here
if (!Page.IsPostBack)
{
ddList1.DataSource = GetCategories(0);
ddList1.DataBind();

//add default item
ListItem _liDefault = new ListItem("Please select Category ->","");
ddList1.Items.Insert(0,_liDefault);
ddList1.Attributes.Add("id","ddList1");

//GenerateNewDropDown(Convert.ToInt64(ddList1.SelectedValue));

System.Collections.ArrayList _CatList = new ArrayList();
System.Collections.ArrayList _PrevDDList = new ArrayList();

ViewState["CatList"] = _CatList;
ViewState["PrevDDList"] = _PrevDDList;
ViewState["ddListCount"] = 0;
}
else
{
System.Collections.ArrayList _CatList = (ArrayList)ViewState["CatList"];

for (int i = 0; i < _CatList.Count; i++)
{
GenerateNewDropDown(Convert.ToInt64(_CatList));
}

//DisablePrevious(this.Page);
}
}

public DataTable GetCategories(long catid)
{
//Create Instance of Connection and Command Object
SqlConnection oConnection = new
SqlConnection(ConfigurationSettings.AppSettings.Get("ConnectionString"));
SqlDataAdapter daItems = new
SqlDataAdapter("tPortal_Help_Category_sel_List", oConnection);
//Mark the Command as a SPROC
daItems.SelectCommand.CommandType = CommandType.StoredProcedure;
//Add paramaters to SPROC
SqlParameter paramParentID = new SqlParameter("@parent_id",
SqlDbType.BigInt);
paramParentID.Value = catid;
daItems.SelectCommand.Parameters.Add(paramParentID);
//Create the DataSet
DataSet dsItems = new DataSet();
//Fill DataSet
daItems.Fill(dsItems);
//Close Connection
daItems.SelectCommand.Connection.Close();

return dsItems.Tables[0];
}

public DataTable GetArticles(long catid)
{
//Create Instance of Connection and Command Object
SqlConnection oConnection = new
SqlConnection(ConfigurationSettings.AppSettings.Get("ConnectionString"));
SqlDataAdapter daItems = new SqlDataAdapter("tPortal_Help_sel_List",
oConnection);
//Mark the Command as a SPROC
daItems.SelectCommand.CommandType = CommandType.StoredProcedure;
//Add paramaters to SPROC
SqlParameter paramParentID = new SqlParameter("@category_id",
SqlDbType.BigInt);
paramParentID.Value = catid;
daItems.SelectCommand.Parameters.Add(paramParentID);
//Create the DataSet
DataSet dsItems = new DataSet();
//Fill DataSet
daItems.Fill(dsItems);
//Close Connection
daItems.SelectCommand.Connection.Close();

return dsItems.Tables[0];
}

public DataTable GetArticle(long helpid)
{
//Create Instance of Connection and Command Object
SqlConnection oConnection = new
SqlConnection(ConfigurationSettings.AppSettings.Get("ConnectionString"));
SqlDataAdapter daItems = new SqlDataAdapter("tPortal_Help_sel_GetHelp",
oConnection);
//Mark the Command as a SPROC
daItems.SelectCommand.CommandType = CommandType.StoredProcedure;
//Add paramaters to SPROC
SqlParameter paramParentID = new SqlParameter("@help_id",
SqlDbType.BigInt);
paramParentID.Value = helpid;
daItems.SelectCommand.Parameters.Add(paramParentID);
//Create the DataSet
DataSet dsItems = new DataSet();
//Fill DataSet
daItems.Fill(dsItems);
//Close Connection
daItems.SelectCommand.Connection.Close();

return dsItems.Tables[0];
}


private void ddLists_SelectedIndexChanged(object sender, System.EventArgs
e)
{
DropDownList _ddList = (DropDownList)sender;

GenerateNewDropDown(Convert.ToInt64(_ddList.SelectedValue));
}

private void ddArticles_SelectedIndexChanged(object sender,
System.EventArgs e)
{
DropDownList _ddList = (DropDownList)sender;
if ( _ddList.SelectedIndex > 0 )
{
DataTable _dtArticle =
GetArticle(Convert.ToInt64(_ddList.SelectedValue));
if (_dtArticle.Rows.Count > 0)
{
lblArticleDate.Text =
_dtArticle.Rows[0]["date_lastupdated"].ToString();
lblArticleTitle.Text = _dtArticle.Rows[0]["help_title"].ToString();
lblArticleContent.Text =
_dtArticle.Rows[0]["help_content"].ToString();
}
}
}

private void GenerateNewDropDown(long parentid)
{

DataTable _dtCats = GetCategories(parentid);
DataTable _dtArticleList = new DataTable();
DropDownList _NewDDList = new DropDownList();
_NewDDList.AutoPostBack = true;
_NewDDList.EnableViewState = true;
_NewDDList.SelectedIndexChanged += new
System.EventHandler(this.ddLists_SelectedIndexChanged);
//_NewDDList.ID = "ddList" + Convert.ToString(CountDDLists(this.Page) +
1);
_NewDDList.Attributes.Add("id", "ddList" +
Convert.ToString(CountDDLists(this.Page) + 1));

if (_dtCats.Rows.Count > 0)
{

for (int i = 0; i < _dtCats.Rows.Count; i++)
{
ListItem _liNew = new
ListItem(_dtCats.Rows["category_name"].ToString(),_dtCats.Rows["id"].ToString());
_NewDDList.Items.Add(_liNew);
}

//add default item
ListItem _liDefault = new ListItem("Please select SubCategory ->","");
_NewDDList.Items.Insert(0, _liDefault);

TableCell _newCell = new TableCell();
int _newCellIndex = tblCategory.Rows[0].Cells.Add(_newCell);
tblCategory.Rows[0].Cells[_newCellIndex].Controls.Add(_NewDDList);


//GenerateNewDropDown(Convert.ToInt64(_NewDDList.SelectedValue));

System.Collections.ArrayList _CatList = (ArrayList)ViewState["CatList"];

if (!_CatList.Contains(parentid))
{
_CatList.Add(parentid);
}

}
else
{
//try and display the article list if no children
_dtArticleList = GetArticles(parentid);

if (_dtArticleList.Rows.Count > 0)
{
DropDownList _NewDDList2 = new DropDownList();
_NewDDList2.AutoPostBack = true;
_NewDDList2.EnableViewState = true;
_NewDDList2.SelectedIndexChanged += new
System.EventHandler(this.ddArticles_SelectedIndexChanged);
_NewDDList2.Attributes.Add("id", "ddList" +
Convert.ToString(CountDDLists(this.Page) + 1));

for (int i = 0; i < _dtArticleList.Rows.Count; i++)
{
ListItem _liNew = new
ListItem(_dtArticleList.Rows["help_title"].ToString(),_dtArticleList.Rows["id"].ToString());
_NewDDList2.Items.Add(_liNew);
}

//add default item
ListItem _liDefault = new ListItem("Please select an Article ->","");
_NewDDList2.Items.Insert(0, _liDefault);

TableCell _newCell = new TableCell();
int _newCellIndex = tblCategory.Rows[0].Cells.Add(_newCell);
tblCategory.Rows[0].Cells[_newCellIndex].Controls.Add(_NewDDList2);


System.Collections.ArrayList _CatList =
(ArrayList)ViewState["CatList"];

if (!_CatList.Contains(parentid))
{
_CatList.Add(parentid);
}
}
}
}

private void DisablePrevious(Control parent)
{
StoreDDLists(parent);

System.Collections.ArrayList _PrevDDList =
(ArrayList)ViewState["PrevDDList"];

for (int i = 0; i <= _PrevDDList.Count - 1; i++)
{
DropDownList _ddList =
(DropDownList)Page.FindControl(_PrevDDList.ToString());
_ddList.Enabled = false;
}
}

private void StoreDDLists(Control parent)
{
System.Collections.ArrayList _PrevDDList =
(ArrayList)ViewState["PrevDDList"];

foreach (Control c in parent.Controls)
{
if
(c.GetType().FullName.Equals("System.Web.UI.WebControls.DropDownList"))
{
DropDownList _thisDD = (DropDownList)c;

if (!_PrevDDList.Contains(_thisDD.Attributes["id"].ToString()))
{
_PrevDDList.Add(_thisDD.Attributes["id"].ToString());
}
}
if (c.Controls.Count > 0)
{
StoreDDLists(c);
}
}
}
private int CountDDLists(Control parent)
{
foreach (Control c in parent.Controls)
{
if
(c.GetType().FullName.Equals("System.Web.UI.WebControls.DropDownList"))
{
ViewState["ddListCount"] = (int)ViewState["ddListCount"] + 1;
}
if (c.Controls.Count > 0)
{
CountDDLists(c);
}
}

return (int)ViewState["ddListCount"];
}

private void lbRestart_Click(object sender, System.EventArgs e)
{
ViewState["CatList"] = null;
Response.Redirect("TestDD.aspx");
}

#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
this.lbRestart.Click += new System.EventHandler(this.lbRestart_Click);
this.ddList1.SelectedIndexChanged += new
System.EventHandler(this.ddLists_SelectedIndexChanged);
}
#endregion
}
}
 
D

DotNetJunky

Just in that particular example of code it appeared that way, but i did in
fact try it both ways and still no luck.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top