Composite Controls
Date: 05/03/07
(C Sharp) Keywords: no keywords
Hey guys. I'm having a problem writing a Composite Server Control, so I figured I'd actually try to post a question here. The Composite Control is basically a Label and a DropDownList. My problem is that anytime the a PostBack occurs, I lose the SelectedIndex. Anyone have any suggestions? I'll provide part of the code behind the cut :
public class AddNewDropDownListEventArgs : EventArgs {
private String m_sNewValue;
public String NewValue {
get { return m_sNewValue; }
}
public AddNewDropDownListEventArgs( String newValue ) {
m_sNewValue = newValue;
}
///
/// Keeps the user from having to cast it out from being an EventArgs
///
/// this.NewValue
public override string ToString() {
return m_sNewValue;
}
}
///
/// A DropDownList and optional Label that contains an special element that allows the user to add new elements to the list
/// The Special elements are not added until the OnPreRender phase, so the list will act normal until that point.
///
public class AddNewDropDownList : UserControl, INamingContainer, IPostBackEventHandler {
protected Label m_oLabel;
protected DropDownList m_oDropDownList;
public event EventHandler AddNew;
public String Label {
get { return (String)ViewState["Label"]; }
set { ViewState["Label"] = value; }
}
public ListItemCollection Items {
get { return m_oDropDownList.Items; }
}
public int SelectedIndex {
get { return m_oDropDownList.SelectedIndex; }
set { m_oDropDownList.SelectedIndex = value; }
}
public ListItem SelectedItem {
get { return m_oDropDownList.SelectedItem; }
}
public bool IncludeBlankItem {
get {
if( ViewState["IncludeBlankItem"] == null ) {
return true;
}
return (bool)ViewState["IncludeBlankItem"];
}
set { ViewState["IncludeBlankItem"] = value; }
}
public AddNewDropDownList() {
m_oLabel = new Label();
m_oDropDownList = new DropDownList();
}
public void RaisePostBackEvent( string eventArgument ) {
if( AddNew != null ) {
AddNew( this, new AddNewDropDownListEventArgs( eventArgument ) );
}
}
#region AddNewItems
// There are a lot of overloads for this function
// basically, it added the new item right before the [ Add New ] Item
// optionally, it selects it
#endregion
protected void CreateSpecialItems( bool bCreateBlankItem ) {
if( bCreateBlankItem ) Items.Insert( 0, new ListItem( String.Empty, String.Empty ) );
Items.Add( new ListItem( "[ Add New ]", "[ Add New ]" ) );
}
protected override void CreateChildControls() {
// null means don't render, String.Empty means render
// This way, the label can be created for client-side dynamic updating
if( Label != null ) {
m_oLabel.Text = Label;
Controls.Add( m_oLabel );
}
Controls.Add( m_oDropDownList );
base.CreateChildControls();
}
protected override void OnInit( EventArgs e ) {
if( !IsPostBack ) {
CreateSpecialItems( IncludeBlankItem );
}
base.OnInit( e );
}
protected override void LoadViewState( object savedState ) {
if( IsPostBack ) {
ArrayList aItems = (ArrayList)ViewState["anddlItems"];
foreach( ArrayList aItem in aItems ) {
Items.Add( new ListItem( aItem[0].ToString(), aItem[1].ToString() ) );
}
}
}
}
protected override void OnPreRender( EventArgs e ) {
m_oLabel.ID = "Label";
m_oDropDownList.ID = "DropDownList";
m_oDropDownList.Attributes["onchange"] = "getNewItem( this, '" + this.UniqueID + "' );";
StringBuilder sGetNewItemScript = new StringBuilder();
sGetNewItemScript.Append( "function getNewItem( oControl, sUniqueID ) {\n" );
sGetNewItemScript.Append( "\tif( oControl.options[oControl.selectedIndex].value == '[ Add New ]' ) {\n" );
sGetNewItemScript.Append( "\t\tvar retVal = prompt( 'Please input the new value.' );\n" );
sGetNewItemScript.Append( "\t\tif( ( retVal != null ) && ( retVal != '' ) ) {\n" );
sGetNewItemScript.Append( "\t\t\t__doPostBack( sUniqueID, retVal );\n" );
sGetNewItemScript.Append( "\t\t}\n" );
sGetNewItemScript.Append( "\t}\n" );
sGetNewItemScript.Append( "}\n" );
Page.ClientScript.RegisterClientScriptBlock( this.GetType(), "GetNewItem", sGetNewItemScript.ToString(), true );
base.OnPreRender( e );
}
protected override object SaveViewState() {
ArrayList aItems = new ArrayList();
foreach( ListItem oItem in Items ) {
ArrayList aItem = new ArrayList();
aItem.Add( oItem.Text );
aItem.Add( oItem.Value );
aItems.Add( aItem );
}
ViewState["anddlItems"] = aItems;
return base.SaveViewState();
}
}
}
}
Source: http://community.livejournal.com/csharp/84955.html