Reputation: 1396
i have a C# server control which contains one button and one dropdown i want to response.write the dropdown selectedindex to the page while the button click and i dont want to make the event handler on page level (aspx), but i want to code it inside the control and compile as dll
my flow is : construct the button and dropdown, which the control class is load override CreateChildControls to add the button into the server control and bind the click event to it override the RenderControl to add the dropdown to a table, and then render the button
finally i found that the button event can be click, but it just cant get the dropdown selected item, when i select the second one
here is the code :
public class ServerControl1 : WebControl, INamingContainer
{
public ServerControl1()
{
_oBtn = new Button();
_oBtn.ID = "btn";
_oBtn.Text = "Click Me";
_oBtn.Click += new EventHandler(_oBtn_Click);
_ddl = new DropDownList();
_ddl.ID = "ddl";
_ddl.Items.add(new ListItem("xxxxxxxx", "xxxxxxxx"))
_ddl.Items.add(new ListItem("yyyyyyy", "yyyyyyy"))
}
protected override void CreateChildControls()
{
this.Controls.Add(_oBtn);
base.CreateChildControls();
}
public override void RenderControl(HtmlTextWriter writer)
{
AddAttributesToRender(writer);
Table m_oTable = new Table();
TableRow m_oRow;
TableCell m_oCell;
m_oCell = new TableCell();
m_oCell.Controls.Add(_ddl);
m_oRow.Cells.Add(m_oCell);
m_oTable.Rows.Add(m_oRow);
m_oTable.RenderControl(writer);
_oBtn.RenderControl(writer);
}
protected void _oBtn_Click(object sender, EventArgs e)
{
if (_ddl.SelectedIndex != 0)
{
Page.Response.Redirect(Url + "&f0=" + _ddl.SelectedIndex);
}
else
{
Page.Response.Write("nonononon");
}
}
}
Upvotes: 1
Views: 621
Reputation: 1667
In order to preserve the state (ViewState) of the dynamically added controls (button, dropdownlist), you have to make sure they are added to the Control Tree hierarchy.
-> Page
-> WebControl
-> Button
-> DropdownList
The proper way to initialize the Child controls in a WebControl is in the Init event.
/// <summary>
/// Initialization of controls
/// </summary>
/// <param name="e"></param>
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
_oBtn = new Button();
_ddl = new DropDownList();
m_oTable = new Table();
m_oRow = new TableRow();
m_oCell = new TableCell();
_oBtn.ID = "btn";
_oBtn.Text = "Click Me";
_oBtn.Click += new EventHandler(_oBtn_Click);
_ddl.ID = "ddl";
_ddl.Items.Add(new ListItem("xxxxxxxx", "xxxxxxxx"));
_ddl.Items.Add(new ListItem("yyyyyyy", "yyyyyyy"));
_ddl.EnableViewState = true;
_ddl.AutoPostBack = false;
}
If IsPostaback than before the Load event of the control, the state of the Child controls is restored from the ViewState (ex: current button text and selected index are set).
Next step is to add this child controls in the Control Tree hierarchy in the CreateChildControls
method
protected override void CreateChildControls()
{
m_oCell.Controls.Add(_ddl);
m_oRow.Cells.Add(m_oCell);
m_oTable.Rows.Add(m_oRow);
this.Controls.Add(_oBtn);
this.Controls.Add(m_oTable);
base.CreateChildControls();
}
and to render the control. You have to avoid initializing or adding controls at this point on:
public override void RenderControl(HtmlTextWriter writer)
{
m_oTable.RenderControl(writer);
_oBtn.RenderControl(writer);
_txt.RenderControl(writer);
}
Upvotes: 1