Hi Stech,
I've just created a new composite control which support dynamic databindig
to populate its sub dropdownlist and dynamically creating sub control
items(label and textbox) according to the selected DropDownList item....
All the control created code are in the CreateChildControls (and a private
helper function........). I've tested in my own enviornment which works
well (win2k3 server, ASP.NET 1.1....). Here is the complete control code:
====================================
namespace DTControlLib
{
/// <summary>
/// Summary description for DynamicCompositeControl.
/// </summary>
[DefaultProperty("Text"),
ToolboxData("<{0}
ynamicCompositeControl
runat=server></{0}
ynamicCompositeControl>")]
[Designer(typeof(DynamicCompositeControlDesigner),typeof(IDesigner))]
public class DynamicCompositeControl :
System.Web.UI.WebControls.WebControl, INamingContainer
{
private bool _databind = false;
private Table _tb;
private Table _tbsub;
private DropDownList _list;
private object _datasource = null;
private string _textfield = null;
private string _valuefield = null;
public DynamicCompositeControl(){}
public object DataSource
{
get{return _datasource;}
set{_datasource = value;}
}
public string DataTextField
{
get{return _textfield;}
set{_textfield = value;}
}
public string DataValueField
{
get{return _valuefield;}
set{_valuefield = value;}
}
public string CurrentItemValue
{
get{
string itemvalue = ViewState["current_item"] as string;
if(itemvalue == null)
{
return string.Empty;
}
else
{
return itemvalue;
}
}
set
{
ViewState["current_item"] = value;
}
}
public override void DataBind()
{
EnsureChildControls();
_list.DataSource = this.DataSource;
if(_textfield != null) _list.DataTextField = _textfield;
if(_valuefield != null) _list.DataValueField = _valuefield;
_list.DataBind();
_list.SelectedIndex = 0;
ViewState["current_item"] = _list.SelectedValue;
_databind = true;
CreateDynamicChildControls();
ChildControlsCreated = true;
}
//override createchildcontrols
protected override void CreateChildControls()
{
Controls.Clear();
_tb = new Table();
_tb.ID = "tbMain";
_tb.CellPadding = 0;_tb.CellSpacing = 0;
_tb.Width = Unit.Percentage(100);
_tb.Rows.Add(new TableRow());
_tb.Rows.Add(new TableRow());
_tb.Rows.Add(new TableRow());
_tb.Rows[0].Cells.Add(new TableCell());
_tb.Rows[1].Cells.Add(new TableCell());
_tb.Rows[2].Cells.Add(new TableCell());
Controls.Add(_tb);
_list = new DropDownList();
_list.ID = "lstItems";
_list.AutoPostBack = true;
_list.SelectedIndexChanged += new
EventHandler(listItems_SelectedIndexChanged);
_tb.Rows[0].Cells[0].Controls.Add(_list);
Button btn = new Button();
btn.ID = "btnSubmit";
btn.Text = "Submit";
btn.Click +=new EventHandler(btnSubmit_Click);
_tb.Rows[2].Cells[0].Controls.Add(btn);
CreateDynamicChildControls();
}
//custom child control creation method
private void CreateDynamicChildControls()
{
_tb.Rows[1].Cells[0].Controls.Clear();
int len = 0;
len = CurrentItemValue.Length;
if(len == 0)
{
Label lbl = new Label();
lbl.ID = "lblMessage";
lbl.Text = "No Current Selected Item...";
lbl.Font.Size = FontUnit.Point(20);
_tb.Rows[1].Cells[0].Controls.Add(lbl);
}
else
{
_tbsub = new Table();
_tbsub.ID = "tbSub";
_tbsub.CellPadding = 0;_tbsub.CellSpacing = 0;
_tbsub.Width = Unit.Percentage(100);
_tb.Rows[1].Cells[0].Controls.Add(_tbsub);
for(int i=1;i<=len;i++)
{
Label lblName = new Label();
lblName.ID = "lblName" + i;
lblName.Text = "Name: ";
TextBox txt = new TextBox();
txt.ID = "txtName" + i;
TableRow tr = new TableRow();
TableCell tc = new TableCell();
tc.Controls.Add(lblName);
tc.Controls.Add(txt);
tr.Cells.Add(tc);
_tbsub.Rows.Add(tr);
}
}
}
private void listItems_SelectedIndexChanged(object sender, EventArgs e)
{
CurrentItemValue = _list.SelectedValue;
CreateDynamicChildControls();
}
private void btnSubmit_Click(object sender, EventArgs e)
{
if(_tbsub != null)
{
foreach(TableRow tr in _tbsub.Rows)
{
TextBox txt = tr.Cells[0].Controls[1] as TextBox;
if(txt != null)
{
Page.Response.Write("<br>" + txt.ID + ": " + txt.Text);
}
}
}
}
}
public class DynamicCompositeControlDesigner : ControlDesigner
{
public override string GetDesignTimeHtml()
{
return "<br><font size='20' color='red'>DynamicCompositeControl
Design-Time HTML.</font>";
}
}
}
=================================================
And below is a test page's code:
============================
private void Page_Load(object sender, System.EventArgs e)
{
if(!IsPostBack)
{
string[] items = {"hi","hello", "bye", "good luck", "welcome", "Good
morning"};
this.DynamicCompositeControl1.DataSource = items;
this.DynamicCompositeControl1.DataBind();
}
}
============================
Hope helps. Thanks,
Steven Cheng
Microsoft Online Support
Get Secure!
www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
--------------------
| X-Tomcat-ID: 120854178
| References: <
[email protected]>
<
[email protected]>
<
[email protected]>
<
[email protected]>
| MIME-Version: 1.0
| Content-Type: text/plain
| Content-Transfer-Encoding: 7bit
| From: (e-mail address removed) (Steven Cheng[MSFT])
| Organization: Microsoft
| Date: Sat, 12 Nov 2005 08:33:24 GMT
| Subject: RE: Composite control, postback and change control tree
| X-Tomcat-NG: microsoft.public.dotnet.framework.aspnet.webcontrols
| Message-ID: <
[email protected]>
| Newsgroups: microsoft.public.dotnet.framework.aspnet.webcontrols
| Lines: 271
| Path: TK2MSFTNGXA02.phx.gbl
| Xref: TK2MSFTNGXA02.phx.gbl
microsoft.public.dotnet.framework.aspnet.webcontrols:31109
| NNTP-Posting-Host: TOMCATIMPORT1 10.201.218.122
|
| Thanks for your followup Stech,
|
| yes, my former example just hard coded some list items and use Visible to
| control the displaying of different items. However, it's abit strange
that
| the postback not work on yourside. Anyway, I'll try building a new one
| which dynamically creating control structure according to the binded
items
| and current selected item in DropDownlist.... I'll update you soon.
|
| Thanks,
|
| Steven Cheng
| Microsoft Online Support
|
| Get Secure!
www.microsoft.com/security
| (This posting is provided "AS IS", with no warranties, and confers no
| rights.)
|
|
|
| --------------------
| | Thread-Topic: Composite control, postback and change control tree
| | thread-index: AcXmFOHCCAs0OmUETaOf+Lzsk0ZCaQ==
| | X-WBNR-Posting-Host: 128.194.92.153
| | From: "=?Utf-8?B?U1RlY2g=?=" <
[email protected]>
| | References: <
[email protected]>
| <
[email protected]>
| <
[email protected]>
| | Subject: RE: Composite control, postback and change control tree
| | Date: Thu, 10 Nov 2005 08:36:21 -0800
| | Lines: 284
| | Message-ID: <
[email protected]>
| | MIME-Version: 1.0
| | Content-Type: text/plain;
| | charset="Utf-8"
| | Content-Transfer-Encoding: 7bit
| | X-Newsreader: Microsoft CDO for Windows 2000
| | Content-Class: urn:content-classes:message
| | Importance: normal
| | Priority: normal
| | X-MimeOLE: Produced By Microsoft MimeOLE V6.00.3790.0
| | Newsgroups: microsoft.public.dotnet.framework.aspnet.webcontrols
| | NNTP-Posting-Host: TK2MSFTNGXA03.phx.gbl 10.40.2.250
| | Path: TK2MSFTNGXA02.phx.gbl!TK2MSFTNGXA01.phx.gbl!TK2MSFTNGXA03.phx.gbl
| | Xref: TK2MSFTNGXA02.phx.gbl
| microsoft.public.dotnet.framework.aspnet.webcontrols:31058
| | X-Tomcat-NG: microsoft.public.dotnet.framework.aspnet.webcontrols
| |
| | Steven,
| | Thanks for the reply. I tried your code but it does not work. The
| postback
| | does nothing. Even if it was working, that is not what I am looking for
-
| | sorry for not being clear.
| |
| | In your approach, you have hardcoded the value 10 and you are showing
and
| | hiding controls. Instead, I want to be able to load n controls based on
| the
| | postback value of the dropdownlist - ie. we are *changing* the control
| tree
| | instead of hiding controls.
| |
| | So I am looking for a way to do this without a hide/show method but
| rather
| | load only the required controls.
| |
| | Thanks for looking into this.
| |
| |
| |
| | "Steven Cheng[MSFT]" wrote:
| |
| | > Hi Stech,
| | >
| | > How are you doing on this issue? Does the suggestion and code snipeet
| in my
| | > last reply helps a little? If there're anything else we can help,
| please
| | > feel free to post here. Thanks,
| | >
| | > Steven Cheng
| | > Microsoft Online Support
| | >
| | > Get Secure!
www.microsoft.com/security
| | > (This posting is provided "AS IS", with no warranties, and confers no
| | > rights.)
| | > --------------------
| | > | X-Tomcat-ID: 266458778
| | > | References: <
[email protected]>
| | > | MIME-Version: 1.0
| | > | Content-Type: text/plain
| | > | Content-Transfer-Encoding: 7bit
| | > | From: (e-mail address removed) (Steven Cheng[MSFT])
| | > | Organization: Microsoft
| | > | Date: Fri, 04 Nov 2005 13:35:54 GMT
| | > | Subject: RE: Composite control, postback and change control tree
| | > | X-Tomcat-NG: microsoft.public.dotnet.framework.aspnet.webcontrols
| | > | Message-ID: <
[email protected]>
| | > | Newsgroups: microsoft.public.dotnet.framework.aspnet.webcontrols
| | > | Lines: 140
| | > | Path: TK2MSFTNGXA01.phx.gbl
| | > | Xref: TK2MSFTNGXA01.phx.gbl
| | > microsoft.public.dotnet.framework.aspnet.webcontrols:11674
| | > | NNTP-Posting-Host: tomcatimport2.phx.gbl 10.201.218.182
| | > |
| | > | Hi Stech,
| | > |
| | > | Welcome to ASPNET newsgroup.
| | > | Regarding on the Createing composite control which has DropDownlist
| and
| | > | textBox list question you mentioned, based on my experience, we can
| put
| | > the
| | > | most control tree creating code in the "CreateChildControls"
method,
| | > | however , since we need to hidden and visible some certain control
| | > | according to the PostBack event's result, I think we'd better also
| | > utilize
| | > | the
| | > | PreRender event(not Render) , in PreRender, we can do UI Attribute
| | > setting
| | > | such as adjusting some certain control's visibility....
| | > |
| | > | Also, as for your scenario, we need to persist the current selected
| Index
| | > | and last selected Index and ViewState will be the proper place for
| | > storing
| | > | such variable. I've made a simple example which has a DropDownlist
| and
| | > | TextBoxes mapping to all the DropDownList items. When
dropdownlist's
| | > | selected index changes, we'll hidden the orginal visible textbox
and
| make
| | > | the new selected one visible. For dropdownlist items, I'm
currently
| | > hard
| | > | coding fix number of items , for dynamic items or databinding,
it'll
| be
| | > | more complex:
| | > |
| | > |
| | > | ======================
| | > | namespace ControlWebApp.customcontrols
| | > | {
| | > | /// <summary>
| | > | /// Summary description for MyCompositeControl.
| | > | /// </summary>
| | > | [DefaultProperty("Text"),
| | > | ToolboxData("<{0}:MyCompositeControl
| | > | runat=server></{0}:MyCompositeControl>")]
| | > | [DesignerAttribute(typeof(MyCompositeControlDesigner),
| | > typeof(IDesigner))]
| | > | public class MyCompositeControl :
| System.Web.UI.WebControls.WebControl,
| | > | INamingContainer
| | > | {
| | > | private string text;
| | > | private DropDownList lst;
| | > |
| | > | private TextBox[] txts;
| | > |
| | > |
| | > | private int _oldindex = 0;
| | > | private int _currentindex = 0;
| | > |
| | > |
| | > |
| | > | [Bindable(true),
| | > | Category("Appearance"),
| | > | DefaultValue("")]
| | > | public string Text
| | > | {
| | > | get
| | > | {
| | > | return text;
| | > | }
| | > |
| | > | set
| | > | {
| | > | text = value;
| | > | }
| | > | }
| | > |
| | > |
| | > | public int CurrentIndex
| | > | {
| | > | get
| | > | {
| | > | return _currentindex;
| | > | }
| | > | set
| | > | {
| | > |
| | > | _currentindex = value;
| | > | }
| | > | }
| | > |
| | > | protected override void CreateChildControls()
| | > | {
| | > | Controls.Clear();
| | > | Controls.Add(
| | > | new LiteralControl(
| | > | "<table ><tr><td>"
| | > | )
| | > | );
| | > |
| | > | lst = new DropDownList();
| | > | lst.ID = "lstItems";
| | > | lst.AutoPostBack = true;
| | > | lst.SelectedIndexChanged +=new
| EventHandler(lst_SelectedIndexChanged);
| | > |
| | > | for(int i=0;i<10;i++)
| | > | {
| | > | lst.Items.Add("Item_" + i);
| | > | }
| | > |
| | > | Controls.Add(lst);
| | > |
| | > | txts = new TextBox[lst.Items.Count];
| | > |
| | > | for(int j=0;j<lst.Items.Count;j++)
| | > | {
| | > | txts[j] = new TextBox();
| | > | txts[j].ID = "txtItem_"+j;
| | > | txts[j].Visible = false;
| | > | Controls.Add(txts[j]);
| | > |
| | > | }
| | > |
| | > |
| | > | Controls.Add(
| | > | new LiteralControl(
| | > | "</td></tr></table >"
| | > | )
| | > | );
| | > | }
| | > |
| | > |
| | > | protected override void LoadViewState(object savedState)
| | > | {
| | > | Triplet mystate = (Triplet)savedState;
| | > |
| | > | _currentindex = (int)mystate.Second;
| | > |
| | > | base.LoadViewState (mystate.First);
| | > | }
| | > |
| | > | protected override object SaveViewState()
| | > | {
| | > | Triplet mystate = new Triplet();
| | > |
| | > | mystate.First = base.SaveViewState ();
| | > | mystate.Second = _currentindex;
| | > |
| | > | return mystate;
| | > | }
| | > |
| | > |
| | > |
| | > | protected override void OnPreRender(EventArgs e)
| | > | {
| | > |
| | > | txts[_oldindex].Visible = false;
| | > | txts[_currentindex].Visible = true;
| | > | }
| | > |
| | > |
| | > | protected void lst_SelectedIndexChanged(object sender, EventArgs
e)
| | > | {
| | > |
| | > | _oldindex = CurrentIndex;
| | > | CurrentIndex = lst.SelectedIndex;
| | > | }
| | > |
| | > | }
| | > |
| | > | public class MyCompositeControlDesigner : ControlDesigner
| | > | {
| | > | public override string GetDesignTimeHtml()
| | > | {
| | > | return "<font size='20' color='red'>MyCompositeControl</font>";
| | > | }
| | > |
| | > |
| | > | }
| | > |
| | > |
| | > | }
| | > | ==============================
| | > |
| | > | You can have a look to see whether it helps , if you'd like to
| implement
| | > | more complex ones, please feel free to let me know.
| | > |
| | > | Thanks,
| | > |
| | > | Steven Cheng
| | > | Microsoft Online Support
| | > |
| | > | Get Secure!
www.microsoft.com/security
| | > | (This posting is provided "AS IS", with no warranties, and confers
no
| | > | rights.)
| | > |
| | > | --------------------
| | > | | Thread-Topic: Composite control, postback and change control tree
| | > | | thread-index: AcXg/HxdHE2yOtWnTh+j4CB9PfUddA==
| | > | | X-WBNR-Posting-Host: 165.91.46.44
| | > | | From: "=?Utf-8?B?U1RlY2g=?=" <
[email protected]>
| | > | | Subject: Composite control, postback and change control tree
| | > | | Date: Thu, 3 Nov 2005 20:59:07 -0800
| | > | | Lines: 12
| | > | | Message-ID: <
[email protected]>
| | > | | MIME-Version: 1.0
| | > | | Content-Type: text/plain;
| | > | | charset="Utf-8"
| | > | | Content-Transfer-Encoding: 7bit
| | > | | X-Newsreader: Microsoft CDO for Windows 2000
| | > | | Content-Class: urn:content-classes:message
| | > | | Importance: normal
| | > | | Priority: normal
| | > | | X-MimeOLE: Produced By Microsoft MimeOLE V6.00.3790.0
| | > | | Newsgroups: microsoft.public.dotnet.framework.aspnet.webcontrols
| | > | | NNTP-Posting-Host: TK2MSFTNGXA03.phx.gbl 10.40.2.250
| | > | | Path: TK2MSFTNGXA01.phx.gbl!TK2MSFTNGXA03.phx.gbl
| | > | | Xref: TK2MSFTNGXA01.phx.gbl
| | > | microsoft.public.dotnet.framework.aspnet.webcontrols:11669
| | > | | X-Tomcat-NG: microsoft.public.dotnet.framework.aspnet.webcontrols
| | > | |
| | > | |
| | > | | I am writing a WebControl that has a dropdownlist and 1..n
TextBox
| | > | controls.
| | > | | Autopostback is enabled for the dropdownlist. When the first
| dropdown
| | > | item is
| | > | | selected, I want 1 TextBox control to be rendered, when the
second
| | > | dropdown
| | > | | item is selcted I want 2 TextBoxes to be rendered and so on..
| | > | |
| | > | | I would to have everything in the control tree
| (CreateChildControls)
| | > and
| | > | not
| | > | | in the Render method.
| | > | |
| | > | | Please advise.
| | > | |
| | > | | Thanks in advance.
| | > | |
| | > |
| | > |
| | >
| | >
| |
|
|