Dynamic control state changes lost on Postback

Discussion in 'ASP .Net Building Controls' started by Christophe Peillet, Jan 4, 2006.

  1. I have been developing a set of custom controls that include several
    dynamically generated controls inside them (for example, 'SupportTextBox'
    include a textbox, a label, and a validation icon used if the field is
    mandatory). These controls also support AJAX callbacks. Everything works
    fine when used in 'Callback' mode, but when the controls are used as normal
    form controls (non-Callback, meaning they are rendered as standard TextBoxes,
    CheckBoxes, etc.), the postback destroys any changes made to the dynamically
    generated controls.

    For example, if the 'TextBoxText' properties initial value is set to
    String.Empty, and I change this value to 'Test' on the form, and raise a
    postback via a button, the value is always String.Empty when the page reloads.

    I know there are some specific issues with PostBack and dynamic controls
    (I've spent a week trying to understand how to fix this issue, but only run
    in circles at this point).

    If someone can show me (clearly) how I can maintain the state of the dynamic
    controls after a postback, it would be enormously appreciated. I've read
    perhaps 30 articles dealing with this in some manner or another, but have
    never found something clear that address my problem. (I.e., I'm not asking
    because I'm lazy and haven't tried to solve this myself).

    A sample class is included below to help see where the problem may be. For
    reference sake, this control (SupportTextBox) inherits from several others
    objects in the hierarchy, but the relevant logic should all be contained here.

    -----
    [SupportTextBox.cs]
    -----

    using System;
    using System.IO;
    using System.Collections.Generic;
    using System.Text;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.Design;
    using System.Web.UI.Design.WebControls;
    using System.ComponentModel;
    using System.ComponentModel.Design;
    using System.Diagnostics;
    using Telerik.WebControls;

    namespace Epson.EEE.Web.UI.FormControls
    {
    /// <summary>
    /// An AJAX enabled TextBox control, which automatically applies the
    Epson style guide to its appearance.
    /// </summary>
    /// <seealso cref="T:SupportTextBoxDesigner"/>
    /// <seealso cref="T:SupportTextBoxActionList"/>
    [Designer(typeof(SupportTextBoxDesigner))]
    [DefaultProperty("Text")]
    [DefaultEvent("TextChanged")]
    [ToolboxData("<{0}:SupportTextBox runat=server></{0}:SupportTextBox>")]
    public class SupportTextBox : SupportFormLabelledControl
    {
    #region Internal Fields

    // Any third-party or external controls that you wish to add to the
    this
    // control, such as buttons, labels, etc., should be declared here.

    // Declare any required controls/objects
    private CallbackTextBox m_txt;
    private CallbackLabel m_lbl;
    private IconPopupControl m_icn;

    #endregion

    #region Event Handlers

    // Declare any events that will be raised by this control.

    /// <summary>
    /// Fires when the textbox's text content is changed, and focus is
    lost from the control. (Please note that this event only fires when <see
    cref="P:SupportTextBox.CallbackEnabled"/> is set to True.)
    /// </summary>
    [Category("Action")]
    [Description("Fires when the text is changed. (Please note that
    this event only fires when CallbackEnabled is set to True.)")]
    public event EventHandler TextChanged;

    #endregion

    #region Constructor

    // Default values for properties should ONLY be defined in the the
    // class constructor. If you set properties elsewhere, such as in the
    // OnLoad event, you will make the control insensitive to external,
    // tag-level settings.

    /// <summary>
    /// Initializes a new instance of the <see cref="SupportTextBox"/>
    class.
    /// </summary>
    public SupportTextBox()
    {
    // Set default values
    this.SetDefaultValues();
    }

    #endregion

    #region Protected Methods (Page Events)

    /// <summary>
    /// Raises the <see cref="E:System.Web.UI.Control.Init"></see> event.
    /// </summary>
    /// <param name="e">An <see cref="T:System.EventArgs"></see> object
    that contains the event data.</param>
    protected override void OnInit(EventArgs e)
    {
    base.OnInit(e);
    }

    /// <summary>
    /// Raises the <see cref="E:System.Web.UI.Control.Load"></see> event.
    /// </summary>
    /// <param name="e">The <see cref="T:System.EventArgs"></see> object
    that contains the event data.</param>
    protected override void OnLoad(EventArgs e)
    {
    // This method captures the controls Load event (declared and
    bound in the
    // class constructor). RunTime rendering takes place in this
    method (as
    // opposed to DesignMode rendering, which takes place elsewhere).

    // Call base Load method
    base.OnLoad(e);

    EnsureChildControls();

    // Make sure we are not running in DesignMode
    if (!(this.DesignMode))
    {
    this.SetRunTimeProperties();
    }
    }

    /// <summary>
    /// Called by the ASP.NET page framework to notify server controls
    that use
    /// composition-based implementation to create any child controls
    they contain
    /// in preparation for posting back or rendering.
    /// </summary>
    protected override void CreateChildControls()
    {
    // Clear the control collection
    Controls.Clear();

    // Any dependant controls used in this custom control must
    // be added to the control 'hierarchy'. If they are not added
    // to the control collection, they will not be visible to other
    // controls on the page.

    // Instantiate any dependant controls
    m_txt = new CallbackTextBox();
    m_lbl = new CallbackLabel();
    m_icn = new IconPopupControl();

    // Register any events associated with dependant controls
    m_txt.TextChanged += new EventHandler(TextChangedEvent);

    // Add them to the control collection
    Controls.Add(m_txt);
    Controls.Add(m_lbl);
    Controls.Add(m_icn);

    // Call base method
    base.CreateChildControls();
    }

    /// <summary>
    /// Renders the contents of the control to the specified writer.
    This method is used primarily by control developers.
    /// </summary>
    /// <param name="output">A <see
    cref="T:System.Web.UI.HtmlTextWriter"></see> that represents the output
    stream to render HTML content on the client.</param>
    protected override void RenderContents(HtmlTextWriter output)
    {
    EnsureChildControls();

    // Render temporary values if running in DesignMode. This
    allows users
    // to see the control as it will appear in the RunTime
    environment.
    if (this.DesignMode)
    {
    SetDesignTimeProperties();
    }
    else
    {
    SetRunTimeProperties();
    }

    // Create temporary HtmlTextWriter placeholder
    StringBuilder stringBuilder = new StringBuilder();
    StringWriter stringWriter = new StringWriter(stringBuilder);
    HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter);

    // Create table to hold results
    htmlWriter.RenderBeginTag(HtmlTextWriterTag.Table);
    htmlWriter.RenderBeginTag(HtmlTextWriterTag.Tr);

    // Render dependent controls
    switch (this.LabelPosition)
    {
    case Position.Left:
    // Label
    htmlWriter.AddAttribute(HtmlTextWriterAttribute.Style,
    "width: " + this.LabelWidth.ToString() + ";");
    htmlWriter.RenderBeginTag(HtmlTextWriterTag.Td);
    m_lbl.RenderControl(htmlWriter);
    htmlWriter.RenderEndTag();
    // Textbox
    htmlWriter.RenderBeginTag(HtmlTextWriterTag.Td);
    m_txt.RenderControl(htmlWriter);
    // Render the popup icon control if required
    if (this.Required)
    {
    m_icn.RenderControl(htmlWriter);
    }
    htmlWriter.RenderEndTag();
    htmlWriter.RenderEndTag();
    break;
    case Position.Top:
    // Label
    htmlWriter.AddAttribute(HtmlTextWriterAttribute.Style,
    "width: " + this.LabelWidth.ToString() + ";");
    htmlWriter.RenderBeginTag(HtmlTextWriterTag.Td);
    m_lbl.RenderControl(htmlWriter);
    htmlWriter.RenderEndTag();
    htmlWriter.RenderEndTag();
    // Textbox
    htmlWriter.RenderBeginTag(HtmlTextWriterTag.Tr);
    htmlWriter.AddAttribute(HtmlTextWriterAttribute.Colspan,
    "2");
    htmlWriter.RenderBeginTag(HtmlTextWriterTag.Td);
    m_txt.RenderControl(htmlWriter);
    // Render the popup icon control if required
    if (this.Required)
    {
    m_icn.RenderControl(htmlWriter);
    }
    htmlWriter.RenderEndTag();
    htmlWriter.RenderEndTag();
    break;
    case Position.Right:
    // Textbox
    htmlWriter.RenderBeginTag(HtmlTextWriterTag.Td);
    m_txt.RenderControl(htmlWriter);
    // Render the popup icon control if required
    if (this.Required)
    {
    m_icn.RenderControl(htmlWriter);
    }
    htmlWriter.RenderEndTag();
    // Label
    htmlWriter.AddAttribute(HtmlTextWriterAttribute.Style,
    "width: " + this.LabelWidth.ToString() + ";");
    htmlWriter.RenderBeginTag(HtmlTextWriterTag.Td);
    m_lbl.RenderControl(htmlWriter);
    htmlWriter.RenderEndTag();
    htmlWriter.RenderEndTag();
    break;
    case Position.Bottom:
    // Textbox
    htmlWriter.RenderBeginTag(HtmlTextWriterTag.Td);
    m_txt.RenderControl(htmlWriter);
    // Render the popup icon control if required
    if (this.Required)
    {
    m_icn.RenderControl(htmlWriter);
    }
    htmlWriter.RenderEndTag();
    htmlWriter.RenderEndTag();
    // Label
    htmlWriter.RenderBeginTag(HtmlTextWriterTag.Tr);
    htmlWriter.AddAttribute(HtmlTextWriterAttribute.Colspan,
    "2");
    htmlWriter.RenderBeginTag(HtmlTextWriterTag.Td);
    m_lbl.RenderControl(htmlWriter);
    htmlWriter.RenderEndTag();
    htmlWriter.RenderEndTag();
    break;
    default:
    Debug.Assert(false);
    break;
    }

    // Close table tag
    htmlWriter.RenderEndTag();

    // If you wish to make any modifications to the raw Html code
    // before it is send to the output stream (for example, ensuring
    // that the code is XHtml compliant, etc.), you can make the
    // modifications to the 'rawHtml' field below. This code will
    // then be sent to the real Html output stream.
    string rawHtml = stringBuilder.ToString();
    output.Write(rawHtml);
    }

    /// <summary>
    /// Raised when the user changes the content of the textbox. This
    event only fires when <see cref="P:SupportTextBox.CallbackEnabled"/> is set
    to True.
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The <see cref="System.EventArgs"/> instance
    containing the event data.</param>
    protected void TextChangedEvent(object sender, EventArgs e)
    {
    // ToDo: Is there a better way to do this (update properties
    automatically)
    this.TextboxText = ((CallbackTextBox)sender).Text;

    // Make sure we are not running in DesignMode
    if (!(this.DesignMode))
    {
    if (!(TextChanged == null))
    {
    this.TextChanged(sender, new EventArgs());
    }
    }
    }

    #endregion

    #region Private Methods

    /// <summary>
    /// Sets the control's default values.
    /// </summary>
    private void SetDefaultValues()
    {
    // Set properties to default values
    this.TextboxCssClass = SharedConstants.SupportForm_TextBoxStyle;
    this.TextboxMaxLength = 0;
    this.TextboxReadOnly = false;
    this.TextboxText = string.Empty;
    }

    /// <summary>
    /// Sets the properties of this control when executing in a design
    time environment.
    /// </summary>
    private void SetDesignTimeProperties()
    {
    // Associate dependent control properties with this control's
    properties
    m_lbl.CssClass = this.LabelCssClass;
    m_lbl.Text = this.LabelText == string.Empty ?
    m_lbl.Text = "[LabelText]" :
    m_lbl.Text = this.LabelText;
    m_lbl.Visible = this.LabelVisible;
    m_lbl.RadControlsDir = this.ScriptsPath;
    m_lbl.CallbackEnabled = this.CallbackEnabled;
    m_lbl.DisableAtCallback = this.DisableAtCallback;
    m_lbl.Enabled = this.Enabled;
    m_txt.MaxLength = this.TextboxMaxLength;
    m_txt.ReadOnly = this.TextboxReadOnly;
    m_txt.RadControlsDir = this.ScriptsPath;
    m_txt.DisableAtCallback = this.DisableAtCallback;
    m_txt.CallbackEnabled = this.CallbackEnabled;
    m_txt.CssClass = this.TextboxCssClass;
    m_txt.Enabled = this.Enabled;
    m_icn.ImageUrl = this.WarningImageUrl;
    m_icn.ImageAlign = this.ImageAlign;
    m_icn.EmptyImageUrl = this.EmptyImageUrl;
    m_icn.MessageStyle = this.MessageStyle;
    m_icn.PopupText = this.PopupText;
    m_icn.PopupTextResourceKey = this.PopupTextResourceKey;
    m_icn.PopupTitle = this.PopupTitle;
    m_icn.PopupTitleResourceKey = this.PopupTitleResourceKey;
    m_icn.WarningIconVisible = this.WarningIconVisible;
    m_icn.Enabled = this.Enabled;
    m_icn.CssClass = this.WarningIconCssStyle;
    }

    /// <summary>
    /// Sets the properties of this control when executing in a run time
    environment.
    /// </summary>
    private void SetRunTimeProperties()
    {
    // Associate dependent control properties with this control's
    properties
    m_lbl.CssClass = this.LabelCssClass;
    m_lbl.Text = this.LabelText;
    m_lbl.Visible = this.LabelVisible;
    m_lbl.RadControlsDir = this.ScriptsPath;
    m_lbl.CallbackEnabled = this.CallbackEnabled;
    m_lbl.DisableAtCallback = this.DisableAtCallback;
    m_lbl.Enabled = this.Enabled;
    m_txt.MaxLength = this.TextboxMaxLength;
    m_txt.ReadOnly = this.TextboxReadOnly;
    m_txt.RadControlsDir = this.ScriptsPath;
    m_txt.DisableAtCallback = this.DisableAtCallback;
    m_txt.CallbackEnabled = this.CallbackEnabled;
    m_txt.CssClass = this.TextboxCssClass;
    m_txt.Enabled = this.Enabled;
    m_icn.ImageUrl = this.WarningImageUrl;
    m_icn.ImageAlign = this.ImageAlign;
    m_icn.EmptyImageUrl = this.EmptyImageUrl;
    m_icn.MessageStyle = this.MessageStyle;
    m_icn.PopupText = this.PopupText;
    m_icn.PopupTextResourceKey = this.PopupTextResourceKey;
    m_icn.PopupTitle = this.PopupTitle;
    m_icn.PopupTitleResourceKey = this.PopupTitleResourceKey;
    m_icn.WarningIconVisible = this.WarningIconVisible;
    m_icn.Enabled = this.Enabled;
    m_icn.CssClass = this.WarningIconCssStyle;
    }

    #endregion

    #region Protected Properties

    /// <summary>
    /// Gets or sets the number of controls in the Control collection
    /// (used to manage a counter stored in ViewState).
    /// </summary>
    /// <value>The number of controls in the Control collection.</value>
    protected int NumberOfControls
    {
    get
    {
    int i = (int)ViewState["NumControls"];
    return i;
    }
    set
    {
    ViewState["NumControls"] = value;
    }
    }

    #endregion

    #region Public Properties

    /// <summary>
    /// Gets or sets the textbox CSS class.
    /// </summary>
    /// <value>The textbox CSS class.</value>
    [Bindable(true)]
    [Category("Textbox")]
    [Description("The Css Class associated with the textbox.")]
    [Localizable(false)]
    public string TextboxCssClass
    {
    get
    {
    string s = (string)ViewState["TextboxCssClass"];
    return s;
    }
    set
    {
    Debug.Assert(value != null, "Warning: TextboxCssClass
    property is null!");
    if (value != null)
    {
    ViewState["TextboxCssClass"] = value;
    }
    else
    {
    throw new NullReferenceException("TextboxCssClass can
    not be assigned a null value.");
    }
    }
    }


    /// <summary>
    /// Gets or sets a value indicating whether the textbox is read only.
    /// </summary>
    /// <value><c>true</c> if read only; otherwise, <c>false</c>.</value>
    [Bindable(true)]
    [Category("Textbox")]
    [DefaultValue(typeof(bool), "False")]
    [Description("Whether the textbox contents can be modified by users
    or not.")]
    [Localizable(false)]
    public bool TextboxReadOnly
    {
    get
    {
    bool b = (bool)ViewState["TextboxReadOnly"];
    return b;
    }
    set
    {
    ViewState["TextboxReadOnly"] = value;
    }
    }

    /// <summary>
    /// Gets or sets the textbox text.
    /// </summary>
    /// <value>The textbox text.</value>
    [Bindable(true)]
    [Category("Textbox")]
    [DefaultValue(typeof(string), "")]
    [Description("The text that will be displayed in the textbox.")]
    [Localizable(true)]
    public string TextboxText
    {
    get
    {
    string s = (string)ViewState["TextboxText"];
    return s;
    }
    set
    {
    Debug.Assert(value != null, "Warning: TextboxText property
    is null!");
    if (value != null)
    {
    ViewState["TextboxText"] = value;
    this.EnsureChildControls();
    }
    else
    {
    throw new NullReferenceException("TextboxText can not be
    assigned a null value.");
    }
    }
    }

    /// <summary>
    /// Gets or sets the maximum length (in characters) of the text box
    content.
    /// </summary>
    /// <value>The maximum length of the text box content.</value>
    [Bindable(true)]
    [Category("Textbox")]
    [Description("The maximum number of characters that can be entered
    in the textbox.")]
    [Localizable(false)]
    public int TextboxMaxLength
    {
    get
    {
    int i = (int)ViewState["TextboxMaxLength"];
    return i;
    }
    set
    {
    ViewState["TextboxMaxLength"] = value;
    }
    }

    #endregion

    }
    }
    Christophe Peillet, Jan 4, 2006
    #1
    1. Advertising

  2. Christophe Peillet

    Teemu Keiski Guest

    Hi,

    with quick glance, you have child controls which handle postback? In that
    case, your control should also implement INamingContainer interface, so that
    postback data is correctly routed.

    And what comes to those properties which wrap straight to the properties of
    child controls, for example TextBoxMaxLength, wouldn't it make more sense
    store it just once. If you have it like this:

    public int TextboxMaxLength
    > {
    > get
    > {
    > int i = (int)ViewState["TextboxMaxLength"];
    > return i;
    > }
    > set
    > {
    > ViewState["TextboxMaxLength"] = value;
    > }
    > }


    and it's later set also for the TextBox after viewstate tracking has started
    (but before saving of viewstate), it basically is saved twice, once to the
    ViewState of this proprrty and second time within ViewState of your child
    control (assuming it has ViewState enabled).Therefore in "wrapper" property
    wouldn't this be enough?

    public int TextboxMaxLength
    {
    get
    {
    EnsureChildControls();
    return m_txt.MaxLength;
    }
    set
    {
    EnsureChildControls();
    m_txt.MaxLength = value;
    }
    }


    --
    Teemu Keiski
    ASP.NET MVP, AspInsider
    Finland, EU
    http://blogs.aspadvice.com/joteke

    "Christophe Peillet" <> wrote in message
    news:...
    >I have been developing a set of custom controls that include several
    > dynamically generated controls inside them (for example, 'SupportTextBox'
    > include a textbox, a label, and a validation icon used if the field is
    > mandatory). These controls also support AJAX callbacks. Everything works
    > fine when used in 'Callback' mode, but when the controls are used as
    > normal
    > form controls (non-Callback, meaning they are rendered as standard
    > TextBoxes,
    > CheckBoxes, etc.), the postback destroys any changes made to the
    > dynamically
    > generated controls.
    >
    > For example, if the 'TextBoxText' properties initial value is set to
    > String.Empty, and I change this value to 'Test' on the form, and raise a
    > postback via a button, the value is always String.Empty when the page
    > reloads.
    >
    > I know there are some specific issues with PostBack and dynamic controls
    > (I've spent a week trying to understand how to fix this issue, but only
    > run
    > in circles at this point).
    >
    > If someone can show me (clearly) how I can maintain the state of the
    > dynamic
    > controls after a postback, it would be enormously appreciated. I've read
    > perhaps 30 articles dealing with this in some manner or another, but have
    > never found something clear that address my problem. (I.e., I'm not
    > asking
    > because I'm lazy and haven't tried to solve this myself).
    >
    > A sample class is included below to help see where the problem may be.
    > For
    > reference sake, this control (SupportTextBox) inherits from several others
    > objects in the hierarchy, but the relevant logic should all be contained
    > here.
    >
    > -----
    > [SupportTextBox.cs]
    > -----
    >
    > using System;
    > using System.IO;
    > using System.Collections.Generic;
    > using System.Text;
    > using System.Web;
    > using System.Web.UI;
    > using System.Web.UI.WebControls;
    > using System.Web.UI.Design;
    > using System.Web.UI.Design.WebControls;
    > using System.ComponentModel;
    > using System.ComponentModel.Design;
    > using System.Diagnostics;
    > using Telerik.WebControls;
    >
    > namespace Epson.EEE.Web.UI.FormControls
    > {
    > /// <summary>
    > /// An AJAX enabled TextBox control, which automatically applies the
    > Epson style guide to its appearance.
    > /// </summary>
    > /// <seealso cref="T:SupportTextBoxDesigner"/>
    > /// <seealso cref="T:SupportTextBoxActionList"/>
    > [Designer(typeof(SupportTextBoxDesigner))]
    > [DefaultProperty("Text")]
    > [DefaultEvent("TextChanged")]
    > [ToolboxData("<{0}:SupportTextBox runat=server></{0}:SupportTextBox>")]
    > public class SupportTextBox : SupportFormLabelledControl
    > {
    > #region Internal Fields
    >
    > // Any third-party or external controls that you wish to add to the
    > this
    > // control, such as buttons, labels, etc., should be declared here.
    >
    > // Declare any required controls/objects
    > private CallbackTextBox m_txt;
    > private CallbackLabel m_lbl;
    > private IconPopupControl m_icn;
    >
    > #endregion
    >
    > #region Event Handlers
    >
    > // Declare any events that will be raised by this control.
    >
    > /// <summary>
    > /// Fires when the textbox's text content is changed, and focus is
    > lost from the control. (Please note that this event only fires when <see
    > cref="P:SupportTextBox.CallbackEnabled"/> is set to True.)
    > /// </summary>
    > [Category("Action")]
    > [Description("Fires when the text is changed. (Please note that
    > this event only fires when CallbackEnabled is set to True.)")]
    > public event EventHandler TextChanged;
    >
    > #endregion
    >
    > #region Constructor
    >
    > // Default values for properties should ONLY be defined in the the
    > // class constructor. If you set properties elsewhere, such as in
    > the
    > // OnLoad event, you will make the control insensitive to external,
    > // tag-level settings.
    >
    > /// <summary>
    > /// Initializes a new instance of the <see cref="SupportTextBox"/>
    > class.
    > /// </summary>
    > public SupportTextBox()
    > {
    > // Set default values
    > this.SetDefaultValues();
    > }
    >
    > #endregion
    >
    > #region Protected Methods (Page Events)
    >
    > /// <summary>
    > /// Raises the <see cref="E:System.Web.UI.Control.Init"></see>
    > event.
    > /// </summary>
    > /// <param name="e">An <see cref="T:System.EventArgs"></see> object
    > that contains the event data.</param>
    > protected override void OnInit(EventArgs e)
    > {
    > base.OnInit(e);
    > }
    >
    > /// <summary>
    > /// Raises the <see cref="E:System.Web.UI.Control.Load"></see>
    > event.
    > /// </summary>
    > /// <param name="e">The <see cref="T:System.EventArgs"></see>
    > object
    > that contains the event data.</param>
    > protected override void OnLoad(EventArgs e)
    > {
    > // This method captures the controls Load event (declared and
    > bound in the
    > // class constructor). RunTime rendering takes place in this
    > method (as
    > // opposed to DesignMode rendering, which takes place
    > elsewhere).
    >
    > // Call base Load method
    > base.OnLoad(e);
    >
    > EnsureChildControls();
    >
    > // Make sure we are not running in DesignMode
    > if (!(this.DesignMode))
    > {
    > this.SetRunTimeProperties();
    > }
    > }
    >
    > /// <summary>
    > /// Called by the ASP.NET page framework to notify server controls
    > that use
    > /// composition-based implementation to create any child controls
    > they contain
    > /// in preparation for posting back or rendering.
    > /// </summary>
    > protected override void CreateChildControls()
    > {
    > // Clear the control collection
    > Controls.Clear();
    >
    > // Any dependant controls used in this custom control must
    > // be added to the control 'hierarchy'. If they are not added
    > // to the control collection, they will not be visible to other
    > // controls on the page.
    >
    > // Instantiate any dependant controls
    > m_txt = new CallbackTextBox();
    > m_lbl = new CallbackLabel();
    > m_icn = new IconPopupControl();
    >
    > // Register any events associated with dependant controls
    > m_txt.TextChanged += new EventHandler(TextChangedEvent);
    >
    > // Add them to the control collection
    > Controls.Add(m_txt);
    > Controls.Add(m_lbl);
    > Controls.Add(m_icn);
    >
    > // Call base method
    > base.CreateChildControls();
    > }
    >
    > /// <summary>
    > /// Renders the contents of the control to the specified writer.
    > This method is used primarily by control developers.
    > /// </summary>
    > /// <param name="output">A <see
    > cref="T:System.Web.UI.HtmlTextWriter"></see> that represents the output
    > stream to render HTML content on the client.</param>
    > protected override void RenderContents(HtmlTextWriter output)
    > {
    > EnsureChildControls();
    >
    > // Render temporary values if running in DesignMode. This
    > allows users
    > // to see the control as it will appear in the RunTime
    > environment.
    > if (this.DesignMode)
    > {
    > SetDesignTimeProperties();
    > }
    > else
    > {
    > SetRunTimeProperties();
    > }
    >
    > // Create temporary HtmlTextWriter placeholder
    > StringBuilder stringBuilder = new StringBuilder();
    > StringWriter stringWriter = new StringWriter(stringBuilder);
    > HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter);
    >
    > // Create table to hold results
    > htmlWriter.RenderBeginTag(HtmlTextWriterTag.Table);
    > htmlWriter.RenderBeginTag(HtmlTextWriterTag.Tr);
    >
    > // Render dependent controls
    > switch (this.LabelPosition)
    > {
    > case Position.Left:
    > // Label
    > htmlWriter.AddAttribute(HtmlTextWriterAttribute.Style,
    > "width: " + this.LabelWidth.ToString() + ";");
    > htmlWriter.RenderBeginTag(HtmlTextWriterTag.Td);
    > m_lbl.RenderControl(htmlWriter);
    > htmlWriter.RenderEndTag();
    > // Textbox
    > htmlWriter.RenderBeginTag(HtmlTextWriterTag.Td);
    > m_txt.RenderControl(htmlWriter);
    > // Render the popup icon control if required
    > if (this.Required)
    > {
    > m_icn.RenderControl(htmlWriter);
    > }
    > htmlWriter.RenderEndTag();
    > htmlWriter.RenderEndTag();
    > break;
    > case Position.Top:
    > // Label
    > htmlWriter.AddAttribute(HtmlTextWriterAttribute.Style,
    > "width: " + this.LabelWidth.ToString() + ";");
    > htmlWriter.RenderBeginTag(HtmlTextWriterTag.Td);
    > m_lbl.RenderControl(htmlWriter);
    > htmlWriter.RenderEndTag();
    > htmlWriter.RenderEndTag();
    > // Textbox
    > htmlWriter.RenderBeginTag(HtmlTextWriterTag.Tr);
    >
    > htmlWriter.AddAttribute(HtmlTextWriterAttribute.Colspan,
    > "2");
    > htmlWriter.RenderBeginTag(HtmlTextWriterTag.Td);
    > m_txt.RenderControl(htmlWriter);
    > // Render the popup icon control if required
    > if (this.Required)
    > {
    > m_icn.RenderControl(htmlWriter);
    > }
    > htmlWriter.RenderEndTag();
    > htmlWriter.RenderEndTag();
    > break;
    > case Position.Right:
    > // Textbox
    > htmlWriter.RenderBeginTag(HtmlTextWriterTag.Td);
    > m_txt.RenderControl(htmlWriter);
    > // Render the popup icon control if required
    > if (this.Required)
    > {
    > m_icn.RenderControl(htmlWriter);
    > }
    > htmlWriter.RenderEndTag();
    > // Label
    > htmlWriter.AddAttribute(HtmlTextWriterAttribute.Style,
    > "width: " + this.LabelWidth.ToString() + ";");
    > htmlWriter.RenderBeginTag(HtmlTextWriterTag.Td);
    > m_lbl.RenderControl(htmlWriter);
    > htmlWriter.RenderEndTag();
    > htmlWriter.RenderEndTag();
    > break;
    > case Position.Bottom:
    > // Textbox
    > htmlWriter.RenderBeginTag(HtmlTextWriterTag.Td);
    > m_txt.RenderControl(htmlWriter);
    > // Render the popup icon control if required
    > if (this.Required)
    > {
    > m_icn.RenderControl(htmlWriter);
    > }
    > htmlWriter.RenderEndTag();
    > htmlWriter.RenderEndTag();
    > // Label
    > htmlWriter.RenderBeginTag(HtmlTextWriterTag.Tr);
    >
    > htmlWriter.AddAttribute(HtmlTextWriterAttribute.Colspan,
    > "2");
    > htmlWriter.RenderBeginTag(HtmlTextWriterTag.Td);
    > m_lbl.RenderControl(htmlWriter);
    > htmlWriter.RenderEndTag();
    > htmlWriter.RenderEndTag();
    > break;
    > default:
    > Debug.Assert(false);
    > break;
    > }
    >
    > // Close table tag
    > htmlWriter.RenderEndTag();
    >
    > // If you wish to make any modifications to the raw Html code
    > // before it is send to the output stream (for example,
    > ensuring
    > // that the code is XHtml compliant, etc.), you can make the
    > // modifications to the 'rawHtml' field below. This code will
    > // then be sent to the real Html output stream.
    > string rawHtml = stringBuilder.ToString();
    > output.Write(rawHtml);
    > }
    >
    > /// <summary>
    > /// Raised when the user changes the content of the textbox.
    > This
    > event only fires when <see cref="P:SupportTextBox.CallbackEnabled"/> is
    > set
    > to True.
    > /// </summary>
    > /// <param name="sender">The sender.</param>
    > /// <param name="e">The <see cref="System.EventArgs"/> instance
    > containing the event data.</param>
    > protected void TextChangedEvent(object sender, EventArgs e)
    > {
    > // ToDo: Is there a better way to do this (update properties
    > automatically)
    > this.TextboxText = ((CallbackTextBox)sender).Text;
    >
    > // Make sure we are not running in DesignMode
    > if (!(this.DesignMode))
    > {
    > if (!(TextChanged == null))
    > {
    > this.TextChanged(sender, new EventArgs());
    > }
    > }
    > }
    >
    > #endregion
    >
    > #region Private Methods
    >
    > /// <summary>
    > /// Sets the control's default values.
    > /// </summary>
    > private void SetDefaultValues()
    > {
    > // Set properties to default values
    > this.TextboxCssClass =
    > SharedConstants.SupportForm_TextBoxStyle;
    > this.TextboxMaxLength = 0;
    > this.TextboxReadOnly = false;
    > this.TextboxText = string.Empty;
    > }
    >
    > /// <summary>
    > /// Sets the properties of this control when executing in a design
    > time environment.
    > /// </summary>
    > private void SetDesignTimeProperties()
    > {
    > // Associate dependent control properties with this control's
    > properties
    > m_lbl.CssClass = this.LabelCssClass;
    > m_lbl.Text = this.LabelText == string.Empty ?
    > m_lbl.Text = "[LabelText]" :
    > m_lbl.Text = this.LabelText;
    > m_lbl.Visible = this.LabelVisible;
    > m_lbl.RadControlsDir = this.ScriptsPath;
    > m_lbl.CallbackEnabled = this.CallbackEnabled;
    > m_lbl.DisableAtCallback = this.DisableAtCallback;
    > m_lbl.Enabled = this.Enabled;
    > m_txt.MaxLength = this.TextboxMaxLength;
    > m_txt.ReadOnly = this.TextboxReadOnly;
    > m_txt.RadControlsDir = this.ScriptsPath;
    > m_txt.DisableAtCallback = this.DisableAtCallback;
    > m_txt.CallbackEnabled = this.CallbackEnabled;
    > m_txt.CssClass = this.TextboxCssClass;
    > m_txt.Enabled = this.Enabled;
    > m_icn.ImageUrl = this.WarningImageUrl;
    > m_icn.ImageAlign = this.ImageAlign;
    > m_icn.EmptyImageUrl = this.EmptyImageUrl;
    > m_icn.MessageStyle = this.MessageStyle;
    > m_icn.PopupText = this.PopupText;
    > m_icn.PopupTextResourceKey = this.PopupTextResourceKey;
    > m_icn.PopupTitle = this.PopupTitle;
    > m_icn.PopupTitleResourceKey = this.PopupTitleResourceKey;
    > m_icn.WarningIconVisible = this.WarningIconVisible;
    > m_icn.Enabled = this.Enabled;
    > m_icn.CssClass = this.WarningIconCssStyle;
    > }
    >
    > /// <summary>
    > /// Sets the properties of this control when executing in a run
    > time
    > environment.
    > /// </summary>
    > private void SetRunTimeProperties()
    > {
    > // Associate dependent control properties with this control's
    > properties
    > m_lbl.CssClass = this.LabelCssClass;
    > m_lbl.Text = this.LabelText;
    > m_lbl.Visible = this.LabelVisible;
    > m_lbl.RadControlsDir = this.ScriptsPath;
    > m_lbl.CallbackEnabled = this.CallbackEnabled;
    > m_lbl.DisableAtCallback = this.DisableAtCallback;
    > m_lbl.Enabled = this.Enabled;
    > m_txt.MaxLength = this.TextboxMaxLength;
    > m_txt.ReadOnly = this.TextboxReadOnly;
    > m_txt.RadControlsDir = this.ScriptsPath;
    > m_txt.DisableAtCallback = this.DisableAtCallback;
    > m_txt.CallbackEnabled = this.CallbackEnabled;
    > m_txt.CssClass = this.TextboxCssClass;
    > m_txt.Enabled = this.Enabled;
    > m_icn.ImageUrl = this.WarningImageUrl;
    > m_icn.ImageAlign = this.ImageAlign;
    > m_icn.EmptyImageUrl = this.EmptyImageUrl;
    > m_icn.MessageStyle = this.MessageStyle;
    > m_icn.PopupText = this.PopupText;
    > m_icn.PopupTextResourceKey = this.PopupTextResourceKey;
    > m_icn.PopupTitle = this.PopupTitle;
    > m_icn.PopupTitleResourceKey = this.PopupTitleResourceKey;
    > m_icn.WarningIconVisible = this.WarningIconVisible;
    > m_icn.Enabled = this.Enabled;
    > m_icn.CssClass = this.WarningIconCssStyle;
    > }
    >
    > #endregion
    >
    > #region Protected Properties
    >
    > /// <summary>
    > /// Gets or sets the number of controls in the Control collection
    > /// (used to manage a counter stored in ViewState).
    > /// </summary>
    > /// <value>The number of controls in the Control
    > collection.</value>
    > protected int NumberOfControls
    > {
    > get
    > {
    > int i = (int)ViewState["NumControls"];
    > return i;
    > }
    > set
    > {
    > ViewState["NumControls"] = value;
    > }
    > }
    >
    > #endregion
    >
    > #region Public Properties
    >
    > /// <summary>
    > /// Gets or sets the textbox CSS class.
    > /// </summary>
    > /// <value>The textbox CSS class.</value>
    > [Bindable(true)]
    > [Category("Textbox")]
    > [Description("The Css Class associated with the textbox.")]
    > [Localizable(false)]
    > public string TextboxCssClass
    > {
    > get
    > {
    > string s = (string)ViewState["TextboxCssClass"];
    > return s;
    > }
    > set
    > {
    > Debug.Assert(value != null, "Warning: TextboxCssClass
    > property is null!");
    > if (value != null)
    > {
    > ViewState["TextboxCssClass"] = value;
    > }
    > else
    > {
    > throw new NullReferenceException("TextboxCssClass can
    > not be assigned a null value.");
    > }
    > }
    > }
    >
    >
    > /// <summary>
    > /// Gets or sets a value indicating whether the textbox is read
    > only.
    > /// </summary>
    > /// <value><c>true</c> if read only; otherwise,
    > <c>false</c>.</value>
    > [Bindable(true)]
    > [Category("Textbox")]
    > [DefaultValue(typeof(bool), "False")]
    > [Description("Whether the textbox contents can be modified by users
    > or not.")]
    > [Localizable(false)]
    > public bool TextboxReadOnly
    > {
    > get
    > {
    > bool b = (bool)ViewState["TextboxReadOnly"];
    > return b;
    > }
    > set
    > {
    > ViewState["TextboxReadOnly"] = value;
    > }
    > }
    >
    > /// <summary>
    > /// Gets or sets the textbox text.
    > /// </summary>
    > /// <value>The textbox text.</value>
    > [Bindable(true)]
    > [Category("Textbox")]
    > [DefaultValue(typeof(string), "")]
    > [Description("The text that will be displayed in the textbox.")]
    > [Localizable(true)]
    > public string TextboxText
    > {
    > get
    > {
    > string s = (string)ViewState["TextboxText"];
    > return s;
    > }
    > set
    > {
    > Debug.Assert(value != null, "Warning: TextboxText property
    > is null!");
    > if (value != null)
    > {
    > ViewState["TextboxText"] = value;
    > this.EnsureChildControls();
    > }
    > else
    > {
    > throw new NullReferenceException("TextboxText can not
    > be
    > assigned a null value.");
    > }
    > }
    > }
    >
    > /// <summary>
    > /// Gets or sets the maximum length (in characters) of the text box
    > content.
    > /// </summary>
    > /// <value>The maximum length of the text box content.</value>
    > [Bindable(true)]
    > [Category("Textbox")]
    > [Description("The maximum number of characters that can be entered
    > in the textbox.")]
    > [Localizable(false)]
    > public int TextboxMaxLength
    > {
    > get
    > {
    > int i = (int)ViewState["TextboxMaxLength"];
    > return i;
    > }
    > set
    > {
    > ViewState["TextboxMaxLength"] = value;
    > }
    > }
    >
    > #endregion
    >
    > }
    > }
    Teemu Keiski, Jan 4, 2006
    #2
    1. Advertising

  3. Teemu:

    You are indeed right about unecessarily duplicating the ViewState. I should
    have notice that myself, but I think I've been focusing on this code so much
    that I don't even see things objectively anymore. I was a bit anxious that
    the ViewState would be largish, but I will go back now and see where I can
    minimize it. I had previously implemented INamingContainer, but, when doing
    some debugging to see what the problem was, removed it. Having added it
    back, normal postbacks now seem to work as well as AJAX Callback requests.

    Thanks for taking the time to suggest a fix for this.

    C.
    Christophe Peillet, Jan 5, 2006
    #3
  4. Teemu:

    It seems I do still have problems with the changes you suggested.

    When I change the properties to access the underlying controls directly
    (i.e., assigning to and reading from m_txt, rather than going through the
    ViewState) the postback and callback all work as expected, solving one major
    problem. However, now I am unable to modify the values of the properties in
    the VS IDE. (When I try to change TextBoxText to another value, for example,
    nothing is ever changed.

    The properties that I keep in ViewState work properly, but the ones I access
    directly (via the code you mentionned) are no insensitive to changes in the
    IDE Property Explorer.

    What is quite strange, is that the properties are INDEED being change when I
    examine to HTML code, and when I render the page the new values are present,
    but in the Designer in the IDE (the visual display of the page), these
    modified values are not reflected.

    That is to say: The html source reads as follows:
    <CompanyUI:SupportTextBox ID="SupportTextBox2" runat="server"
    TextboxText="test" />

    You can see that the TextboxText value has been modified, and this shows up
    at run time. However, in the Designer IDE, the property browser and visual
    depiction still show this value as the default, which is String.Empty.

    Any ideas why this might be occuring?
    Christophe Peillet, Jan 5, 2006
    #4
  5. Christophe Peillet

    Teemu Keiski Guest

    Hmm, Did you try having [NotifyParentProperty(true)] attribute on the
    property (top-level one)? I'm thinking if the problem is in that the
    TextBox's Text property (child control) does not send change notification
    up, so property browser does not get updated.

    If it's possible, and you derive from TextBox (it's already a custom,
    inherited control whose Text property you access via top-level property),
    override Text property and append NotifyParentProperty attribute to it .


    --
    Teemu Keiski
    ASP.NET MVP, AspInsider
    Finland, EU
    http://blogs.aspadvice.com/joteke



    "Christophe Peillet" <> wrote in message
    news:...
    > Teemu:
    >
    > It seems I do still have problems with the changes you suggested.
    >
    > When I change the properties to access the underlying controls directly
    > (i.e., assigning to and reading from m_txt, rather than going through the
    > ViewState) the postback and callback all work as expected, solving one
    > major
    > problem. However, now I am unable to modify the values of the properties
    > in
    > the VS IDE. (When I try to change TextBoxText to another value, for
    > example,
    > nothing is ever changed.
    >
    > The properties that I keep in ViewState work properly, but the ones I
    > access
    > directly (via the code you mentionned) are no insensitive to changes in
    > the
    > IDE Property Explorer.
    >
    > What is quite strange, is that the properties are INDEED being change when
    > I
    > examine to HTML code, and when I render the page the new values are
    > present,
    > but in the Designer in the IDE (the visual display of the page), these
    > modified values are not reflected.
    >
    > That is to say: The html source reads as follows:
    > <CompanyUI:SupportTextBox ID="SupportTextBox2" runat="server"
    > TextboxText="test" />
    >
    > You can see that the TextboxText value has been modified, and this shows
    > up
    > at run time. However, in the Designer IDE, the property browser and
    > visual
    > depiction still show this value as the default, which is String.Empty.
    >
    > Any ideas why this might be occuring?
    Teemu Keiski, Jan 5, 2006
    #5
  6. Christophe Peillet

    Teemu Keiski Guest

    And forgot to add, add also RefreshProperties attribute

    http://www.bluevisionsoftware.com/WebSite/TipsAndTricksDetails.aspx?Name=RefreshPropertiesAttribute

    Check also this for further reference:
    http://msdn.microsoft.com/library/d...pgenref/html/cpconpropertyusageguidelines.asp

    E.g in case previous mean is not enough, you might need to have a change
    event for the property.

    By the way what VS version do you have? I recall 2002 having issues with
    composite control subproperties.

    --
    Teemu Keiski
    ASP.NET MVP, AspInsider
    Finland, EU
    http://blogs.aspadvice.com/joteke


    "Teemu Keiski" <> wrote in message
    news:%...
    > Hmm, Did you try having [NotifyParentProperty(true)] attribute on the
    > property (top-level one)? I'm thinking if the problem is in that the
    > TextBox's Text property (child control) does not send change notification
    > up, so property browser does not get updated.
    >
    > If it's possible, and you derive from TextBox (it's already a custom,
    > inherited control whose Text property you access via top-level property),
    > override Text property and append NotifyParentProperty attribute to it .
    >
    >
    > --
    > Teemu Keiski
    > ASP.NET MVP, AspInsider
    > Finland, EU
    > http://blogs.aspadvice.com/joteke
    >
    >
    >
    > "Christophe Peillet" <> wrote in message
    > news:...
    >> Teemu:
    >>
    >> It seems I do still have problems with the changes you suggested.
    >>
    >> When I change the properties to access the underlying controls directly
    >> (i.e., assigning to and reading from m_txt, rather than going through the
    >> ViewState) the postback and callback all work as expected, solving one
    >> major
    >> problem. However, now I am unable to modify the values of the properties
    >> in
    >> the VS IDE. (When I try to change TextBoxText to another value, for
    >> example,
    >> nothing is ever changed.
    >>
    >> The properties that I keep in ViewState work properly, but the ones I
    >> access
    >> directly (via the code you mentionned) are no insensitive to changes in
    >> the
    >> IDE Property Explorer.
    >>
    >> What is quite strange, is that the properties are INDEED being change
    >> when I
    >> examine to HTML code, and when I render the page the new values are
    >> present,
    >> but in the Designer in the IDE (the visual display of the page), these
    >> modified values are not reflected.
    >>
    >> That is to say: The html source reads as follows:
    >> <CompanyUI:SupportTextBox ID="SupportTextBox2" runat="server"
    >> TextboxText="test" />
    >>
    >> You can see that the TextboxText value has been modified, and this shows
    >> up
    >> at run time. However, in the Designer IDE, the property browser and
    >> visual
    >> depiction still show this value as the default, which is String.Empty.
    >>
    >> Any ideas why this might be occuring?

    >
    >
    Teemu Keiski, Jan 5, 2006
    #6
  7. Thanks again for your response. I'm using VS2005 for these controls. I had
    previously tried adding the [RefreshProperties(...)] attribute to the
    property, but still have the same problem. The same with
    NotifyParentProperty, but I haven't tried overriding the base class. (The
    problem is that I will have to override several properties for this.) I can
    try this as well.

    I thought my problem may simply be that I haven't properly understood the
    page model, and I'm placing the DesignTime code in the wrong place. At
    present, in the RenderContents event, I am running a private method named
    'SetDesignTimeProperties'. Perhaps this is the wrong place to be applying to
    various properties to the control for DesignTime display. (It likely occurs
    too late, and is overriding the changed settings.) Why would this change for
    properties set in viewstate, and properties where I access the field itself
    (i.e., m_txt.Text)?

    This is the first time I have tried to develop custom controls that are more
    than something very basic, so it's possible I have put the activity in the
    wrong place.

    If I can steal a few more minutes of you time, can you tell me where in the
    page even model, in your opinion, the following actions should take place:

    1.) Setting a custom control's default properties
    2.) Setting a custom control's properties for display in DesignMode
    3.) Setting a custom control's properties for display at RunTime
    4.?) Restoring properties after a postback?

    Best regards, and thank you again for your assistance. I appreciate it,
    since I've found very little useful assistance on developing custom controls,
    beyond overly simplistic examples/tutorials.

    PS: I noticed that WinForms has a method called RaisePropertyChangedEvent,
    but this doesn't seem to be available in Asp. I suspect this is the same as
    the RefreshProperties(...) attribute, though.
    Christophe Peillet, Jan 5, 2006
    #7
  8. I have tried creating a control that overrides the relevant properties,
    adding the [NotifyParentProperty(true)] attribute, but it doesn't change
    anything. I suspect, as I said previously, that the problem is that I am
    assign the property values to the dynamic controls at the wrong place.

    C.
    Christophe Peillet, Jan 5, 2006
    #8
  9. Christophe Peillet

    Teemu Keiski Guest

    If you want to set something design-time specific, you certainly would do
    that in your control designer.

    As you are using VS2005, I try to reproduce the problem you have (with the
    code you sent in original post). I happen to have Telerik's WebControls also
    so I should be able to reproduce it. This is getting hard to explain, so
    better try it myself.

    Replies:

    1.) Setting a custom control's default properties

    Approach should be that proeprties themselves return a default value when
    they're not set, and DefaultValuer attriobute should point this

    2.) Setting a custom control's properties for display in DesignMode

    Read previous one. If they differ at design-time, using designer to generate
    design-time spedific HTML, is the way.

    3.) Setting a custom control's properties for display at RunTime

    This goes woth what the control has set as property values. :)

    4.?) Restoring properties after a postback?

    ViewState takes care of that as long as controls are added to controls
    collection (with child & dynamic control state), and viewstate tracking has
    started. You should have it pretty much ok with the setup I saw.

    By the way, I recommend asking this at ASP.NET Forums also. There are lots
    of control experts around.

    --
    Teemu Keiski
    ASP.NET MVP, AspInsider
    Finland, EU

    http://blogs.aspadvice.com/joteke
    "Christophe Peillet" <> wrote in message
    news:D...
    > Thanks again for your response. I'm using VS2005 for these controls. I
    > had
    > previously tried adding the [RefreshProperties(...)] attribute to the
    > property, but still have the same problem. The same with
    > NotifyParentProperty, but I haven't tried overriding the base class. (The
    > problem is that I will have to override several properties for this.) I
    > can
    > try this as well.
    >
    > I thought my problem may simply be that I haven't properly understood the
    > page model, and I'm placing the DesignTime code in the wrong place. At
    > present, in the RenderContents event, I am running a private method named
    > 'SetDesignTimeProperties'. Perhaps this is the wrong place to be applying
    > to
    > various properties to the control for DesignTime display. (It likely
    > occurs
    > too late, and is overriding the changed settings.) Why would this change
    > for
    > properties set in viewstate, and properties where I access the field
    > itself
    > (i.e., m_txt.Text)?
    >
    > This is the first time I have tried to develop custom controls that are
    > more
    > than something very basic, so it's possible I have put the activity in the
    > wrong place.
    >
    > If I can steal a few more minutes of you time, can you tell me where in
    > the
    > page even model, in your opinion, the following actions should take
    > place:
    >
    > 1.) Setting a custom control's default properties
    > 2.) Setting a custom control's properties for display in DesignMode
    > 3.) Setting a custom control's properties for display at RunTime
    > 4.?) Restoring properties after a postback?
    >
    > Best regards, and thank you again for your assistance. I appreciate it,
    > since I've found very little useful assistance on developing custom
    > controls,
    > beyond overly simplistic examples/tutorials.
    >
    > PS: I noticed that WinForms has a method called
    > RaisePropertyChangedEvent,
    > but this doesn't seem to be available in Asp. I suspect this is the same
    > as
    > the RefreshProperties(...) attribute, though.
    Teemu Keiski, Jan 5, 2006
    #9
  10. If you prefer, I can send you the solution in c#, since this will be easier
    for you.

    If you send me an email at I will reply with the solution.

    Kevin.
    Christophe Peillet, Jan 5, 2006
    #10
  11. Christophe Peillet

    Teemu Keiski Guest

    I'll reply in mail also, but for the record, due to not having all the
    classes available I had to uncomment IconPopupControl and a few of those
    properties which weren't implemented in the code you posted.

    Basically having it like this:

    //[Designer(typeof(SupportTextBoxDesigner))]
    [DefaultProperty("Text")]
    [DefaultEvent("TextChanged")]
    [ToolboxData("<{0}:SupportTextBox runat=server></{0}:SupportTextBox>")]
    public class SupportTextBox : WebControl,INamingContainer //base class
    changed
    {
    ...
    //Other stuff here, uncommented so that compiles (e.g uncommented
    only those which do not compile)
    ...
    [Bindable(true)]
    [Category("Textbox")]
    [DefaultValue(typeof(string), "")]
    [Description("The text that will be displayed in the textbox.")]
    [Localizable(true)]
    public string TextboxText
    {
    get
    {
    EnsureChildControls();
    return m_txt.Text;

    }
    set
    {
    EnsureChildControls();
    m_txt.Text = value;

    }
    }
    }

    And it works fine at design-time. So questions are: What impact does the
    original base class have, and same question about the designer class
    (SupportTextBoxDesigner)


    --
    Teemu Keiski
    ASP.NET MVP, AspInsider
    Finland, EU
    http://blogs.aspadvice.com/joteke

    "Christophe Peillet" <> wrote in message
    news:...
    > If you prefer, I can send you the solution in c#, since this will be
    > easier
    > for you.
    >
    > If you send me an email at I will reply with the
    > solution.
    >
    > Kevin.
    Teemu Keiski, Jan 5, 2006
    #11
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?SmFtZXM=?=
    Replies:
    3
    Views:
    5,708
    =?Utf-8?B?U2NvdHQgU2ltb25z?=
    Oct 1, 2004
  2. K B
    Replies:
    0
    Views:
    7,055
  3. vcuankitdotnet

    Dynamic Controls Lost On Postback

    vcuankitdotnet, Apr 16, 2007, in forum: ASP .Net
    Replies:
    5
    Views:
    6,180
    Thomas Hansen
    Apr 18, 2007
  4. Bryan

    Dynamic gridview values lost on postback

    Bryan, Aug 22, 2006, in forum: ASP .Net Web Controls
    Replies:
    1
    Views:
    1,037
    Vadivel Kumar
    Aug 23, 2006
  5. Alex

    Dropdown in webpart lost its state after postback

    Alex, Dec 1, 2006, in forum: ASP .Net Web Controls
    Replies:
    1
    Views:
    426
Loading...

Share This Page