|
code
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Changed property values not reflected in DesignModevalidation and Ajax/Callback support built into them, and have finished most of the work, but have a stubborn problem when running in DesignMode. When I try to modify the value of certain properties, the Html code is modified with the new property value (for example '... CheckboxText="MyText" .....'), but the visual display is never updated, and the property explorer window also doesn't reflect the new value. It behaves as if the property is read only, and allow no apparent change, even if it is changing the values beneath the surface, and the changes are visible at RunTime. I suspect the problem is that I have not properly understand the page model properly, and am putting something in the wrong place. (This is my first Custom Control that is more than something simplistic.) If someone can take a look specifically at the methods SetDesignTimeProperties() and SetRunTimeProperties(), I may be running this in the wrong place, but am not sure where else to run them, etc. I will also include the code for the designer in the next post (due to size restrictions). The Custom control is as follows: 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.Drawing; using System.Diagnostics; using Telerik.WebControls; namespace CompanyName.EEE.Web.UI.FormControls { /// <summary> /// An AJAX enabled CheckBox control, which automatically applies the CompanyName style guide to its appearance. /// </summary> /// <seealso cref="T:SupportCheckBoxDesigner"/> /// <seealso cref="T:SupportCheckBoxActionList"/> [Designer(typeof(SupportCheckBoxDesigner))] [DefaultProperty("Text")] [DefaultEvent("OnCheckedChanged")] [ToolboxData("<{0}:SupportCheckBox runat=\"server\"></{0}:SupportCheckBox>")] [ParseChildren(true)] [PersistChildren(false)] [ControlValueProperty("CheckboxChecked")] public class SupportCheckBox : SupportFormLabelledControl, INamingContainer { #region Private 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 CallbackLabel m_lbl; private CallbackCheckBox m_chk; private IconPopupControl m_icn; #endregion #region Event Handlers // Declare any events that will be raised by this control. /// <summary> /// Occurs when the value of the Checked property changes. (This event only fires when <see cref="P:SupportCheckBox.CallbackEnabled"/> is set to True.) /// </summary> [Category("Action")] [Description("Occurs when the value of the Checked property changes. (Please note that this event only fires when CallbackEnabled is set to True.)")] public event EventHandler CheckedChanged; #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="SupportCheckBox"/> class. /// </summary> public SupportCheckBox() { // Set control 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)) { // Associate dependent control properties with this control's properties 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 dependent objects m_lbl = new CallbackLabel(); m_chk = new CallbackCheckBox(); m_icn = new IconPopupControl(); // Register any event associated with dependant objects m_chk.CheckedChanged += new EventHandler(this.RaiseCheckedChanged); // Add them to the control collection Controls.Add(m_lbl); Controls.Add(m_chk); 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) { this.SetDesignTimeProperties(); } // 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(); // Checkbox htmlWriter.RenderBeginTag(HtmlTextWriterTag.Td); m_chk.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(); // Checkbox htmlWriter.RenderBeginTag(HtmlTextWriterTag.Tr); htmlWriter.AddAttribute(HtmlTextWriterAttribute.Colspan, "2"); htmlWriter.RenderBeginTag(HtmlTextWriterTag.Td); m_chk.RenderControl(htmlWriter); // Render the popup icon control if required if (this.Required) { m_icn.RenderControl(htmlWriter); } htmlWriter.RenderEndTag(); htmlWriter.RenderEndTag(); break; case Position.Right: // Checkbox htmlWriter.RenderBeginTag(HtmlTextWriterTag.Td); m_chk.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: // Checkbox htmlWriter.RenderBeginTag(HtmlTextWriterTag.Td); m_chk.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> /// Fires when the value of the Checked property changes. This event only fires when <see cref="P:SupportCheckBox.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 virtual void RaiseCheckedChanged(object sender, EventArgs e) { // ToDo: Is there a better way to do this (update properties automatically) this.CheckboxChecked = ((CallbackCheckBox)sender).Checked; // Ensure that the event has a subscriber. If not, don't fire it. if (CheckedChanged != null) { // Raise the CheckedChanged event CheckedChanged(this, e); } } #endregion #region Private Methods /// <summary> /// Sets the control's default values. /// </summary> private void SetDefaultValues() { // Set properties to default values this.CheckboxChecked = false; this.CheckboxCssClass = SharedConstants.SupportForm_CheckBoxStyle; this.CheckboxEnabled = true; this.CheckboxText = string.Empty; this.CheckboxTextResourceKey = string.Empty; this.CheckboxVisible = true; } /// <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_chk.RadControlsDir = this.ScriptsPath; m_chk.CallbackEnabled = this.CallbackEnabled; m_chk.DisableAtCallback = this.DisableAtCallback; m_chk.Enabled = this.CheckboxEnabled; m_chk.CssClass = this.CheckboxCssClass; m_chk.Text = this.CheckboxText == string.Empty ? m_chk.Text = "[CheckboxText]" : m_chk.Text = this.CheckboxText; m_chk.Visible = this.CheckboxVisible; m_chk.Checked = this.CheckboxChecked; m_chk.AutoPostBack = this.AutoPostback; m_chk.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.CallbackEnabled = this.CallbackEnabled; m_icn.DisableAtCallback = this.DisableAtCallback; 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() { 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_chk.RadControlsDir = this.ScriptsPath; m_chk.CallbackEnabled = this.CallbackEnabled; m_chk.DisableAtCallback = this.DisableAtCallback; m_chk.Enabled = this.CheckboxEnabled; m_chk.CssClass = this.CheckboxCssClass; m_chk.Text = this.CheckboxText; m_chk.Visible = this.CheckboxVisible; m_chk.Checked = this.CheckboxChecked; m_chk.AutoPostBack = this.AutoPostback; m_chk.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.CallbackEnabled = this.CallbackEnabled; m_icn.DisableAtCallback = this.DisableAtCallback; m_icn.Enabled = this.Enabled; m_icn.CssClass = this.WarningIconCssStyle; } #endregion #region Public Properties /// <summary> /// Gets or sets the checkbox CSS class. /// </summary> /// <value>The checkbox CSS class.</value> [Bindable(true)] [Category("Checkbox")] [DefaultValue(typeof(string), "")] [Description("CSS Class name applied to this control.")] [Localizable(false)] public string CheckboxCssClass { get { EnsureChildControls(); return (m_chk.CssClass == null) ? string.Empty : m_chk.CssClass; } set { Debug.Assert(value != null, "Warning: CheckboxCssClass property is null!"); if (value != null) { EnsureChildControls(); m_chk.CssClass = value; } else { throw new NullReferenceException("CheckboxCssClass can not be assigned a null value."); } } } /// <summary> /// Gets or sets the checkbox text. /// </summary> /// <value>The checkbox text.</value> [Bindable(true)] [Category("Checkbox")] [DefaultValue(typeof(string), "")] [Description("The text that will be displayed with the checkbox.")] [Localizable(true)] [NotifyParentProperty(true)] [Browsable(true)] [RefreshProperties(RefreshProperties.All)] public string CheckboxText { get { EnsureChildControls(); return (m_chk.Text == null) ? string.Empty : m_chk.Text; } set { Debug.Assert(value != null, "Warning: CheckboxText property is null!"); if (value != null) { EnsureChildControls(); m_chk.Text = value; } else { throw new NullReferenceException("CheckboxText can not be assigned a null value."); } } } /// <summary> /// Gets or sets a value indicating whether the checkbox is enabled. /// </summary> /// <value><c>true</c> if checkbox enabled; otherwise, <c>false</c>.</value> [Bindable(true)] [Category("Checkbox")] [DefaultValue(typeof(bool), "True")] [Description("Whether or not the Checkbox is enabled.")] [Localizable(false)] public bool CheckboxEnabled { get { EnsureChildControls(); return m_chk.Enabled; } set { EnsureChildControls(); m_chk.Enabled = value; } } /// <summary> /// Gets or sets a value indicating whether the checkbox is checked. /// </summary> /// <value><c>true</c> if checkbox checked; otherwise, <c>false</c>.</value> [Bindable(true)] [Category("Checkbox")] [DefaultValue(typeof(bool), "False")] [Description("Whether or not the Checkbox is selected (checked) or not.")] [Localizable(false)] public bool CheckboxChecked { get { EnsureChildControls(); return m_chk.Checked; } set { EnsureChildControls(); m_chk.Checked = value; } } /// <summary> /// Gets or sets the checkbox text resource key. /// </summary> /// <value>The checkbox text resource key.</value> [Bindable(true)] [Category("Checkbox")] [DefaultValue(typeof(string), "")] [Description("The resource key used when localising the Checkboxes text.")] [Localizable(false)] public string CheckboxTextResourceKey { get { string s = (string)ViewState["CheckboxTextResourceKey"]; return (s == null) ? String.Empty : s; } set { Debug.Assert(value != null, "Warning: CheckboxTextResourceKey property is null!"); if (value != null) { ViewState["CheckboxTextResourceKey"] = value; } else { throw new NullReferenceException("CheckboxTextResourceKey can not be assigned a null value."); } } } /// <summary> /// Gets or sets a value indicating whether the checkbox is visible or not. /// </summary> /// <value><c>true</c> if checkbox visible; otherwise, <c>false</c>.</value> [Bindable(true)] [Category("Checkbox")] [DefaultValue(typeof(bool), "True")] [Description("Whether or not the checkbox is visible.")] [Localizable(false)] public bool CheckboxVisible { get { EnsureChildControls(); return m_chk.Visible; } set { EnsureChildControls(); m_chk.Visible = value; } } #endregion } } Here is the Designer code for this control:
using System; 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 System.Drawing.Design; using Telerik.WebControls; namespace CompanyName.EEE.Web.UI.FormControls { #region Support CheckBox Designer // This designer class manages the control's Smart Tags, including any // properties and actions exposed within then. This particular class // serves as more of a 'manager', since most of the actual work takes // place in the class below that inherits from DesignerActionList. /// <summary> /// The designer used by <see cref="T:SupportCheckBox"></see> to add DesignMode functionality /// (such as SmartTags) to the Visual Studio 2005 IDE. /// </summary> /// <seealso cref="T:SupportTextBoxActionList"/> public class SupportCheckBoxDesigner : CompositeControlDesigner { #region Private Fields private DesignerActionListCollection lists; #endregion #region Public Methods (Overrides) /// <summary> /// Gets the action list collection for the control designer. /// </summary> /// <value></value> /// <returns>A <see cref="T:System.ComponentModel.Design.DesignerActionListCollection"></see> that contains the <see cref="T:System.ComponentModel.Design.DesignerActionList"></see> items for the control designer.</returns> public override DesignerActionListCollection ActionLists { get { if (lists == null) { lists = new DesignerActionListCollection(); lists.Add(new SupportCheckBoxActionList(this.Component)); } return lists; } } #endregion } #endregion #region Support CheckBox Action List // The inherited DesignerActionList class is designed to associate one or more // designer action items with a single component. Most of the actual DesignMode // and Smart Tag work takes place here. /// <summary> /// Associates one or more action items with the <see cref="T:SupportCheckBox"></see> Designer. /// </summary> /// <seealso cref="T:SupportCheckBoxDesigner"/> public class SupportCheckBoxActionList : DesignerActionList { #region Private Fields private SupportCheckBox m_checkBox; private DesignerActionUIService designerActionSvc = null; #endregion #region Constructors /// <summary> /// Initializes a new instance of the <see cref="SupportCheckBoxActionList"/> class. /// </summary> /// <param name="component">A component related to the <see cref="T:System.ComponentModel.Design.DesignerActionList"></see>.</param> public SupportCheckBoxActionList(IComponent component) : base(component) {this.m_checkBox = (SupportCheckBox)component; this.designerActionSvc = ((DesignerActionUIService)(GetService(typeof(DesignerActionUIService)))); } #endregion #region Public Methods (Overrides) // This method populates the actual Smart Tag form. If you wish to change the // order that the properties appear in, this is the place to do so. /// <summary> /// Returns the collection of <see cref="T:System.ComponentModel.Design.DesignerActionItem"></see> objects contained in the list. /// </summary> /// <returns> /// A <see cref="T:System.ComponentModel.Design.DesignerActionItem"></see> array that contains the items in this list. /// </returns> public override DesignerActionItemCollection GetSortedActionItems() { DesignerActionItemCollection items = new DesignerActionItemCollection(); items.Add(new DesignerActionHeaderItem("Callback")); items.Add(new DesignerActionTextItem("Adjusts the AJAX functionality of this control", "Callback")); items.Add(new DesignerActionPropertyItem("CallbackEnabled", "Callback Enabled", "Callback", "Whether callback is enabled to this control or not.")); items.Add(new DesignerActionPropertyItem("DisableAtCallback", "Disabled At Callback", "Callback", "Whether this control should be disabled on the form while a callback is in process.")); items.Add(new DesignerActionPropertyItem("AutoPostback", "AutoPostback", "Callback", "Whether this control causes postback as soon as it is checked or unchecked (only relevant if Callback is disabled).")); items.Add(new DesignerActionPropertyItem("ScriptsPath", "Scripts Path", "Callback", "The relative path of the location where the JavaScript files are stores (ex. '~/Scripts/').")); items.Add(new DesignerActionHeaderItem("Required Field Validator")); items.Add(new DesignerActionTextItem("Determines whether this control is mandatory or not.", "Required Field Validator")); items.Add(new DesignerActionPropertyItem("Required", "Required", "Required Field Validator", "Whether this is a 'Required' field or not.")); items.Add(new DesignerActionPropertyItem("WarningIconVisible", "Warning Icon Visible", "Required Field Validator", "Whether the warning icon is displayed or not (should be true when a validation error occurs).")); items.Add(new DesignerActionPropertyItem("WarningImageUrl", "Warning Image Url", "Required Field Validator", "The path/URL of the image to display when a validation error is raised.")); items.Add(new DesignerActionPropertyItem("EmptyImageUrl", "Empty Image Url", "Required Field Validator", "The path/URL of the image to display when no error is present.")); items.Add(new DesignerActionPropertyItem("ImageAlign", "Image Align", "Required Field Validator", "The way the image is aligned on the screen, relative to the label text.")); items.Add(new DesignerActionPropertyItem("MessageStyle", "Message Style", "Required Field Validator", "The type of message that is display when the user clicks on or mouses over the warning icon.")); items.Add(new DesignerActionTextItem("Settings pertaining to the 'PopupMessage' Message Style", "PopupMessage")); items.Add(new DesignerActionPropertyItem("MessageText", "Message", "PopupMessage", "The body message to display in the popup window.")); items.Add(new DesignerActionPropertyItem("MessageTextResourceKey", "Message Resource Key", "PopupMessage", "The resource key for the popup window's body message.")); items.Add(new DesignerActionPropertyItem("MessageTitle", "Title", "PopupMessage", "The title of the message to display in the popup window.")); items.Add(new DesignerActionPropertyItem("MessageTitleResourceKey", "Title Resource Key", "PopupMessage", "The resource key for the popup window's title.")); items.Add(new DesignerActionTextItem("Settings pertaining to the 'UriLink' Message Style", "URI Link")); items.Add(new DesignerActionPropertyItem("LinkUrl", "Link URL", "URI Link", "The URL to open in a new window when the user clicks the warning icon.")); return items; } #endregion #region Private Methods // The properties of a custom control must be set through a proxy property. // If they are modified directly, such as setting the "Text" item in the Smart // Tag to some string such as "OK," the Properties window will not reflect the // changes. Therefore the properties must be set through a proxy, such as through // the method below. /// <summary> /// Gets a PropertyDescriptor for one of the control's properties based on its name. /// This is necessary because properties must be set in the designer by means a 'proxy'. /// </summary> /// <param name="propName">Full name of the property.</param> /// <returns></returns> private PropertyDescriptor GetPropertyByName(string propName) { PropertyDescriptor prop; prop = TypeDescriptor.GetProperties(m_checkBox)[propName]; if (prop == null) { throw new ArgumentException("Property invalid.", propName); } else { return prop; } } #endregion #region Public Properties // All properties that need to be manipulated within the Smart Tag need to // have wrappers. The 'wrapper properties, seen below, are passed to the // parent control by means of the GetPropertyByName method (defined in this // class). The reason for this is detailed in the comments for the // GetPropertyByName method above. /// <summary> /// A wrapper that points to the control's ScriptPath property /// </summary> /// <value>The scripts path.</value> public string ScriptsPath { get { return m_checkBox.ScriptsPath; } set { GetPropertyByName("ScriptsPath").SetValue(m_checkBox, value); } } /// <summary> /// A wrapper that points to the control's CallbackEnabled property /// </summary> /// <value><c>true</c> if callback is enabled; otherwise, <c>false</c>.</value> public bool CallbackEnabled { get { return m_checkBox.CallbackEnabled; } set { GetPropertyByName("CallbackEnabled").SetValue(m_checkBox, value); } } /// <summary> /// A wrapper that points to the control's AutoPostback property /// </summary> /// <value><c>true</c> if AutoPostback is enabled; otherwise, <c>false</c>.</value> public bool AutoPostback { get { return m_checkBox.AutoPostback; } set { GetPropertyByName("AutoPostback").SetValue(m_checkBox, value); } } /// <summary> /// A wrapper that points to the control's DisableAtCallback property /// </summary> /// <value><c>true</c> if disabled during callback; otherwise, <c>false</c>.</value> public bool DisableAtCallback { get { return this.m_checkBox.DisableAtCallback; } set { GetPropertyByName("DisableAtCallback").SetValue(m_checkBox, value); } } /// <summary> /// A wrapper that points to the control's Required property /// </summary> /// <value><c>true</c> if required; otherwise, <c>false</c>.</value> public bool Required { get { return m_checkBox.Required; } set { GetPropertyByName("Required").SetValue(m_checkBox, value); } } /// <summary> /// A wrapper that points to the control's WarningImageUrl property /// </summary> /// <value>The image URL.</value> [Editor("System.Web.UI.Design.ImageUrlEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))] public string WarningImageUrl { get { return m_checkBox.WarningImageUrl; } set { GetPropertyByName("WarningImageUrl").SetValue(m_checkBox, value); } } /// <summary> /// A wrapper that points to the control's EmptyImageUrl property /// </summary> /// <value>The empty image URL.</value> [Editor("System.Web.UI.Design.ImageUrlEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))] public string EmptyImageUrl { get { return m_checkBox.EmptyImageUrl; } set { GetPropertyByName("EmptyImageUrl").SetValue(m_checkBox, value); } } /// <summary> /// A wrapper that points to the control's ImageAlign property /// </summary> /// <value>The image align.</value> public ImageAlign ImageAlign { get { return m_checkBox.ImageAlign; } set { GetPropertyByName("ImageAlign").SetValue(m_checkBox, value); } } /// <summary> /// A wrapper that points to the control's MessageStyle property /// </summary> /// <value>The message style.</value> public MessageStyle MessageStyle { get { return m_checkBox.MessageStyle; } set { GetPropertyByName("MessageStyle").SetValue(m_checkBox, value); } } /// <summary> /// A wrapper that points to the control's MessageText property /// </summary> /// <value>The message text.</value> public string MessageText { get { return m_checkBox.PopupText; } set { GetPropertyByName("PopupText").SetValue(m_checkBox, value); } } /// <summary> /// A wrapper that points to the control's MessageTextResourceKey property /// </summary> /// <value>The message text resource key.</value> public string MessageTextResourceKey { get { return m_checkBox.PopupTextResourceKey; } set { GetPropertyByName("PopupTextResourceKey").SetValue(m_checkBox, value); } } /// <summary> /// A wrapper that points to the control's MessageTitle property /// </summary> /// <value>The message title.</value> public string MessageTitle { get { return m_checkBox.PopupTitle; } set { GetPropertyByName("PopupTitle").SetValue(m_checkBox, value); } } /// <summary> /// A wrapper that points to the control's MessageTitleResourceKey property /// </summary> /// <value>The message title resource key.</value> public string MessageTitleResourceKey { get { return m_checkBox.PopupTitleResourceKey; } set { GetPropertyByName("PopupTitleResourceKey").SetValue(m_checkBox, value); } } /// <summary> /// A wrapper that points to the control's LinkUrl property /// </summary> /// <value>The link URL.</value> [Editor("System.Web.UI.Design.UrlEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))] public string LinkUrl { get { return m_checkBox.LinkUrl; } set { GetPropertyByName("LinkUrl").SetValue(m_checkBox, value); } } /// <summary> /// A wrapper that points to the control's WarningIconVisible property /// </summary> /// <value><c>true</c> if warning icon is visible; otherwise, <c>false</c>.</value> public bool WarningIconVisible { get { return m_checkBox.WarningIconVisible; } set { GetPropertyByName("WarningIconVisible").SetValue(m_checkBox, value); } } #endregion } #endregion } Hi ChristophePeillet,
Welcome to ASPNET newsgroup. As for the custom webserver control's property value changing being reflected in designview quesiton, here are some of my understanding and suggestions: As for Properteis in WebServer Control which related to UI or states of inner controls, we suggest that we store them in a private member field or directly associated with a ViewState key rather than directly expose the inner control's Property to them. And in the custom control's code, we can always put the applying styles or properteis work in PreRender event (or OnPreRender method) since this is the last place we can change control states and at that time we can ensure that the control structure has been well constructed. And for design-time HTML rendering, we suggest that we separate them from teh runtime rendering code, since for Composite control should put as much code in CreateChildControls as possible(avoid put code in Render method....).... Since you can provide a custom Control designer for our custom control, just override the GetDesignTimeHtml method which helps define our custom design-time html of our custom webcontrol: To make the above clear, here is a simple control which expose a BackColor property for inner textbox sub controls and I persist it in viewstate and at design-time, when I change the property in property grid, the design-time html (I use GetDesignTimeHtml method to generate design-time html) will refresh to reflect the chagne: namespace WebControlLib { [ToolboxData("<{0}:ColorTextBox runat=server></{0}:ColorTextBox>")] [Designer(typeof(ColorTextBoxDesigner), typeof(IDesigner))] [ParseChildren(true)] public class ColorTextBox : WebControl, INamingContainer { private TextBox _txt; [Browsable(true), TypeConverter(typeof(WebColorConverter)), DefaultValue(typeof(Color), "White")] public Color TextBoxBackColor { get { object clr =ViewState["txtbgcolor"]; if (clr != null) { return (Color)clr; } return Color.White; } set { ViewState["txtbgcolor"] = value; } } protected override void CreateChildControls() { Controls.Clear(); Table tbMain = new Table(); tbMain.ID = "tbMain"; tbMain.Width = System.Web.UI.WebControls.Unit.Percentage(100); tbMain.BorderStyle = BorderStyle.Solid; tbMain.BorderWidth = 1; tbMain.Rows.Add(new TableRow()); tbMain.Rows[0].Cells.Add(new TableCell()); Controls.Add(tbMain); _txt = new TextBox(); _txt.ID = "txtMain"; _txt.TextChanged += new EventHandler(txt_TextChanged); tbMain.Rows[0].Cells[0].Controls.Add(_txt); } protected override void OnPreRender(EventArgs e) { base.OnPreRender(e); _txt.BackColor = TextBoxBackColor; } protected override void RenderContents(HtmlTextWriter output) { RenderChildren(output); } private void txt_TextChanged(object sender, EventArgs e) { Page.Response.Write("<br>Text: " + ((TextBox)sender).Text); } } public class ColorTextBoxDesigner : ControlDesigner { public override string GetDesignTimeHtml() { ColorTextBox colortxt = this.Component as ColorTextBox; StringBuilder sb = new StringBuilder(); sb.Append("<font size='30' red='red'>"); sb.Append("ColorTextBox,BackColor: " + colortxt.TextBoxBackColor); sb.Append("</font>"); return sb.ToString(); } } } 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.) -------------------- | Thread-Topic: Designer Code for this control <ChristophePeillet@nospam.nospam>| thread-index: AcYU/OQFbs8UjYBfQoWWNss8rEWDRA== | X-WBNR-Posting-Host: 193.172.19.20 | From: =?Utf-8?B?Q2hyaXN0b3BoZSBQZWlsbGV0?= Show quoteHide quote | References: <0CFC74DF-20E5-4DAF-A747-CB79A4D59***@microsoft.com> microsoft.public.dotnet.framework.aspnet.webcontrols:32325| Subject: Designer Code for this control | Date: Mon, 9 Jan 2006 01:13:01 -0800 | Lines: 505 | Message-ID: <4766EEC0-A1DB-4443-ACF1-17956E16B***@microsoft.com> | 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 Show quoteHide quote | X-Tomcat-NG: microsoft.public.dotnet.framework.aspnet.webcontrols SupportCheckBoxActionList(this.Component));| | Here is the Designer code for this control: | | using System; | 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 System.Drawing.Design; | using Telerik.WebControls; | | namespace CompanyName.EEE.Web.UI.FormControls | { | | #region Support CheckBox Designer | | // This designer class manages the control's Smart Tags, including any | // properties and actions exposed within then. This particular class | // serves as more of a 'manager', since most of the actual work takes | // place in the class below that inherits from DesignerActionList. | | /// <summary> | /// The designer used by <see cref="T:SupportCheckBox"></see> to add | DesignMode functionality | /// (such as SmartTags) to the Visual Studio 2005 IDE. | /// </summary> | /// <seealso cref="T:SupportTextBoxActionList"/> | public class SupportCheckBoxDesigner : CompositeControlDesigner | { | #region Private Fields | | private DesignerActionListCollection lists; | | #endregion | | #region Public Methods (Overrides) | | /// <summary> | /// Gets the action list collection for the control designer. | /// </summary> | /// <value></value> | /// <returns>A <see | cref="T:System.ComponentModel.Design.DesignerActionListCollection"></see> | that contains the <see | cref="T:System.ComponentModel.Design.DesignerActionList"></see> items for the | control designer.</returns> | public override DesignerActionListCollection ActionLists | { | get | { | if (lists == null) | { | lists = new DesignerActionListCollection(); | lists.Add(new Show quoteHide quote | } GetPropertyByName("DisableAtCallback").SetValue(m_checkBox, | return lists; | } | } | | #endregion | } | | #endregion | | #region Support CheckBox Action List | | // The inherited DesignerActionList class is designed to associate one | or more | // designer action items with a single component. Most of the actual | DesignMode | // and Smart Tag work takes place here. | | /// <summary> | /// Associates one or more action items with the <see | cref="T:SupportCheckBox"></see> Designer. | /// </summary> | /// <seealso cref="T:SupportCheckBoxDesigner"/> | public class SupportCheckBoxActionList : DesignerActionList | { | #region Private Fields | | private SupportCheckBox m_checkBox; | private DesignerActionUIService designerActionSvc = null; | | #endregion | | #region Constructors | | /// <summary> | /// Initializes a new instance of the <see | cref="SupportCheckBoxActionList"/> class. | /// </summary> | /// <param name="component">A component related to the <see | cref="T:System.ComponentModel.Design.DesignerActionList"></see>.</param> | public SupportCheckBoxActionList(IComponent component) | : base(component) | { | this.m_checkBox = (SupportCheckBox)component; | this.designerActionSvc = | ((DesignerActionUIService)(GetService(typeof(DesignerActionUIService)))); | } | | #endregion | | #region Public Methods (Overrides) | | // This method populates the actual Smart Tag form. If you wish to | change the | // order that the properties appear in, this is the place to do so. | | /// <summary> | /// Returns the collection of <see | cref="T:System.ComponentModel.Design.DesignerActionItem"></see> objects | contained in the list. | /// </summary> | /// <returns> | /// A <see | cref="T:System.ComponentModel.Design.DesignerActionItem"></see> array that | contains the items in this list. | /// </returns> | public override DesignerActionItemCollection GetSortedActionItems() | { | DesignerActionItemCollection items = new | DesignerActionItemCollection(); | items.Add(new DesignerActionHeaderItem("Callback")); | items.Add(new DesignerActionTextItem("Adjusts the AJAX | functionality of this control", "Callback")); | items.Add(new DesignerActionPropertyItem("CallbackEnabled", | "Callback Enabled", "Callback", "Whether callback is enabled to this control | or not.")); | items.Add(new DesignerActionPropertyItem("DisableAtCallback", | "Disabled At Callback", "Callback", "Whether this control should be disabled | on the form while a callback is in process.")); | items.Add(new DesignerActionPropertyItem("AutoPostback", | "AutoPostback", "Callback", "Whether this control causes postback as soon as | it is checked or unchecked (only relevant if Callback is disabled).")); | items.Add(new DesignerActionPropertyItem("ScriptsPath", "Scripts | Path", "Callback", "The relative path of the location where the JavaScript | files are stores (ex. '~/Scripts/').")); | items.Add(new DesignerActionHeaderItem("Required Field | Validator")); | items.Add(new DesignerActionTextItem("Determines whether this | control is mandatory or not.", "Required Field Validator")); | items.Add(new DesignerActionPropertyItem("Required", "Required", | "Required Field Validator", "Whether this is a 'Required' field or not.")); | items.Add(new DesignerActionPropertyItem("WarningIconVisible", | "Warning Icon Visible", "Required Field Validator", "Whether the warning icon | is displayed or not (should be true when a validation error occurs).")); | items.Add(new DesignerActionPropertyItem("WarningImageUrl", | "Warning Image Url", "Required Field Validator", "The path/URL of the image | to display when a validation error is raised.")); | items.Add(new DesignerActionPropertyItem("EmptyImageUrl", "Empty | Image Url", "Required Field Validator", "The path/URL of the image to display | when no error is present.")); | items.Add(new DesignerActionPropertyItem("ImageAlign", "Image | Align", "Required Field Validator", "The way the image is aligned on the | screen, relative to the label text.")); | items.Add(new DesignerActionPropertyItem("MessageStyle", | "Message Style", "Required Field Validator", "The type of message that is | display when the user clicks on or mouses over the warning icon.")); | items.Add(new DesignerActionTextItem("Settings pertaining to the | 'PopupMessage' Message Style", "PopupMessage")); | items.Add(new DesignerActionPropertyItem("MessageText", | "Message", "PopupMessage", "The body message to display in the popup | window.")); | items.Add(new | DesignerActionPropertyItem("MessageTextResourceKey", "Message Resource Key", | "PopupMessage", "The resource key for the popup window's body message.")); | items.Add(new DesignerActionPropertyItem("MessageTitle", | "Title", "PopupMessage", "The title of the message to display in the popup | window.")); | items.Add(new | DesignerActionPropertyItem("MessageTitleResourceKey", "Title Resource Key", | "PopupMessage", "The resource key for the popup window's title.")); | items.Add(new DesignerActionTextItem("Settings pertaining to the | 'UriLink' Message Style", "URI Link")); | items.Add(new DesignerActionPropertyItem("LinkUrl", "Link URL", | "URI Link", "The URL to open in a new window when the user clicks the warning | icon.")); | return items; | } | | #endregion | | #region Private Methods | | // The properties of a custom control must be set through a proxy | property. | // If they are modified directly, such as setting the "Text" item in | the Smart | // Tag to some string such as "OK," the Properties window will not | reflect the | // changes. Therefore the properties must be set through a proxy, | such as through | // the method below. | | /// <summary> | /// Gets a PropertyDescriptor for one of the control's properties | based on its name. | /// This is necessary because properties must be set in the designer | by means a 'proxy'. | /// </summary> | /// <param name="propName">Full name of the property.</param> | /// <returns></returns> | private PropertyDescriptor GetPropertyByName(string propName) | { | PropertyDescriptor prop; | prop = TypeDescriptor.GetProperties(m_checkBox)[propName]; | if (prop == null) | { | throw new ArgumentException("Property invalid.", propName); | } | else | { | return prop; | } | } | | #endregion | | #region Public Properties | | // All properties that need to be manipulated within the Smart Tag | need to | // have wrappers. The 'wrapper properties, seen below, are passed | to the | // parent control by means of the GetPropertyByName method (defined | in this | // class). The reason for this is detailed in the comments for the | // GetPropertyByName method above. | | /// <summary> | /// A wrapper that points to the control's ScriptPath property | /// </summary> | /// <value>The scripts path.</value> | public string ScriptsPath | { | get | { | return m_checkBox.ScriptsPath; | } | set | { | GetPropertyByName("ScriptsPath").SetValue(m_checkBox, value); | } | } | | /// <summary> | /// A wrapper that points to the control's CallbackEnabled property | /// </summary> | /// <value><c>true</c> if callback is enabled; otherwise, | <c>false</c>.</value> | public bool CallbackEnabled | { | get | { | return m_checkBox.CallbackEnabled; | } | set | { | GetPropertyByName("CallbackEnabled").SetValue(m_checkBox, | value); | } | } | | /// <summary> | /// A wrapper that points to the control's AutoPostback property | /// </summary> | /// <value><c>true</c> if AutoPostback is enabled; otherwise, | <c>false</c>.</value> | public bool AutoPostback | { | get | { | return m_checkBox.AutoPostback; | } | set | { | GetPropertyByName("AutoPostback").SetValue(m_checkBox, value); | } | } | | /// <summary> | /// A wrapper that points to the control's DisableAtCallback property | /// </summary> | /// <value><c>true</c> if disabled during callback; otherwise, | <c>false</c>.</value> | public bool DisableAtCallback | { | get | { | return this.m_checkBox.DisableAtCallback; | } | set | { | | value); <c>false</c>.</value>| } | } | | /// <summary> | /// A wrapper that points to the control's Required property | /// </summary> | /// <value><c>true</c> if required; otherwise, Show quoteHide quote | public bool Required GetPropertyByName("WarningIconVisible").SetValue(m_checkBox, | { | get | { | return m_checkBox.Required; | } | set | { | GetPropertyByName("Required").SetValue(m_checkBox, value); | } | } | | /// <summary> | /// A wrapper that points to the control's WarningImageUrl property | /// </summary> | /// <value>The image URL.</value> | [Editor("System.Web.UI.Design.ImageUrlEditor, System.Design, | Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", | typeof(UITypeEditor))] | public string WarningImageUrl | { | get | { | return m_checkBox.WarningImageUrl; | } | set | { | GetPropertyByName("WarningImageUrl").SetValue(m_checkBox, | value); | } | } | | /// <summary> | /// A wrapper that points to the control's EmptyImageUrl property | /// </summary> | /// <value>The empty image URL.</value> | [Editor("System.Web.UI.Design.ImageUrlEditor, System.Design, | Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", | typeof(UITypeEditor))] | public string EmptyImageUrl | { | get | { | return m_checkBox.EmptyImageUrl; | } | set | { | GetPropertyByName("EmptyImageUrl").SetValue(m_checkBox, | value); | } | } | | /// <summary> | /// A wrapper that points to the control's ImageAlign property | /// </summary> | /// <value>The image align.</value> | public ImageAlign ImageAlign | { | get | { | return m_checkBox.ImageAlign; | } | set | { | GetPropertyByName("ImageAlign").SetValue(m_checkBox, value); | } | } | | /// <summary> | /// A wrapper that points to the control's MessageStyle property | /// </summary> | /// <value>The message style.</value> | public MessageStyle MessageStyle | { | get | { | return m_checkBox.MessageStyle; | } | set | { | GetPropertyByName("MessageStyle").SetValue(m_checkBox, value); | } | } | | /// <summary> | /// A wrapper that points to the control's MessageText property | /// </summary> | /// <value>The message text.</value> | public string MessageText | { | get | { | return m_checkBox.PopupText; | } | set | { | GetPropertyByName("PopupText").SetValue(m_checkBox, value); | } | } | | /// <summary> | /// A wrapper that points to the control's MessageTextResourceKey | property | /// </summary> | /// <value>The message text resource key.</value> | public string MessageTextResourceKey | { | get | { | return m_checkBox.PopupTextResourceKey; | } | set | { | | GetPropertyByName("PopupTextResourceKey").SetValue(m_checkBox, value); | } | } | | /// <summary> | /// A wrapper that points to the control's MessageTitle property | /// </summary> | /// <value>The message title.</value> | public string MessageTitle | { | get | { | return m_checkBox.PopupTitle; | } | set | { | GetPropertyByName("PopupTitle").SetValue(m_checkBox, value); | } | } | | /// <summary> | /// A wrapper that points to the control's MessageTitleResourceKey | property | /// </summary> | /// <value>The message title resource key.</value> | public string MessageTitleResourceKey | { | get | { | return m_checkBox.PopupTitleResourceKey; | } | set | { | | GetPropertyByName("PopupTitleResourceKey").SetValue(m_checkBox, value); | } | } | | /// <summary> | /// A wrapper that points to the control's LinkUrl property | /// </summary> | /// <value>The link URL.</value> | [Editor("System.Web.UI.Design.UrlEditor, System.Design, | Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", | typeof(UITypeEditor))] | public string LinkUrl | { | get | { | return m_checkBox.LinkUrl; | } | set | { | GetPropertyByName("LinkUrl").SetValue(m_checkBox, value); | } | } | | /// <summary> | /// A wrapper that points to the control's WarningIconVisible property | /// </summary> | /// <value><c>true</c> if warning icon is visible; otherwise, | <c>false</c>.</value> | public bool WarningIconVisible | { | get | { | return m_checkBox.WarningIconVisible; | } | set | { | Show quoteHide quote | value); | } | } | | #endregion | } | | #endregion | | } | | Steven:
Thank you for your response. I normally place the value of properties in the ViewState, but in this case, I choose to access the control's properties directly, since the underlying control also adds it's value to the ViewState. I would be storing the Textbox's 'Text' value in ViewState twice if I also added it here in this composite control. As per your advice, I have rearranged some of the code, and tried to remove everything from the Render event, instead pushing pushing the relevant code into CreateChildControls(). I have also moved the code where property values are assigned to OnPreRender(), rather than the private SetRunTimeProperties(). For simplicity sake, I have also removed the custom designer. I have included the full modified class below. Unfortunately, my problem still persists. Whenever I make a change to any of my custom properties (such as LabelText, which is defined in the parent class, or TextboxText, which is defined in this class), these values are changed in the underlying HTML code and appear at run time, but never change in DesignMode and the Property Browser is never updated. This makes it almost impossible to meaningfully create controls at DesignTime. If I place some sort of rendering code in a Designer in the 'GetDesignTimeHtml()' method, does it mean I will need to duplicate all of my rendering code in the Designer as well (I hate to have the same code in two places)? The control should work without a designer at all, though, shouldn't it? (I only created one to allow SmartTags support.) If you can give me any other advice on why control's are not being refreshed at DesignTime, it would be appreciated. I'm completely lost with this problem, and am already behind schedule because of it. ;-( Best regards, and thank you for your time. 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"/> // ToDo: Restore Designer // [Designer(typeof(SupportTextBoxDesigner))] [DefaultProperty("Text")] [DefaultEvent("TextChanged")] [ToolboxData("<{0}:SupportTextBox runat=server></{0}:SupportTextBox>")] public class SupportTextBox : SupportFormLabelledControl, INamingContainer { #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) { // Call base Load method base.OnLoad(e); EnsureChildControls(); } /// <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 Table tbl = new Table(); m_txt = new CallbackTextBox(); m_lbl = new CallbackLabel(); m_icn = new IconPopupControl(); // Register any events associated with dependant controls m_txt.TextChanged += new EventHandler(RaiseTextChanged); // Create table object and format it through relevant method tbl = CreateTable(this.LabelPosition); // Add table to the control collection Controls.Add(tbl); // Add controls to the table control collection switch (this.LabelPosition) { case Position.Left: tbl.Rows[0].Cells[0].Controls.Add(m_lbl); tbl.Rows[0].Cells[1].Controls.Add(m_txt); if (this.Required) { tbl.Rows[0].Cells[1].Controls.Add(m_icn); } // Set relevant design properties tbl.Rows[0].Cells[0].Width = new Unit(this.LabelWidth.ToString()); break; case Position.Top: tbl.Rows[0].Cells[0].Controls.Add(m_lbl); tbl.Rows[1].Cells[0].Controls.Add(m_txt); if (this.Required) { tbl.Rows[1].Cells[0].Controls.Add(m_icn); } // Set relevant design properties tbl.Rows[0].Cells[0].Width = new Unit(this.LabelWidth.ToString()); break; case Position.Right: tbl.Rows[0].Cells[0].Controls.Add(m_txt); if (this.Required) { tbl.Rows[0].Cells[0].Controls.Add(m_icn); } tbl.Rows[0].Cells[1].Controls.Add(m_lbl); // Set relevant design properties tbl.Rows[0].Cells[1].Width = new Unit(this.LabelWidth.ToString()); break; case Position.Bottom: tbl.Rows[0].Cells[0].Controls.Add(m_lbl); tbl.Rows[1].Cells[0].Controls.Add(m_txt); if (this.Required) { tbl.Rows[1].Cells[1].Controls.Add(m_icn); } // Set relevant design properties tbl.Rows[0].Cells[0].Width = new Unit(this.LabelWidth.ToString()); break; default: Debug.Assert(false); break; } // Call base method base.CreateChildControls(); } /// <summary> /// Raises the <see cref="E:System.Web.UI.Control.PreRender"></see> event. /// </summary> /// <param name="e">An <see cref="T:System.EventArgs"></see> object that contains the event data.</param> protected override void OnPreRender(EventArgs e) { base.OnPreRender(e); // 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; } /// <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(); // Create temporary HtmlTextWriter placeholder StringBuilder stringBuilder = new StringBuilder(); StringWriter stringWriter = new StringWriter(stringBuilder); HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter); // Render child controls RenderChildren(htmlWriter); // 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 RaiseTextChanged(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> /// Creates the table that will hold the relevant controls. /// </summary> /// <param name="labelPosition">The label position, which is used to /// determine how the table should be arranged.</param> /// <returns>A Table object</returns> private Table CreateTable(Position labelPosition) { Table tbl = new Table(); // Set basic table properties tbl.BorderStyle = BorderStyle.None; tbl.BorderWidth = 0; // Format table according to label position switch (labelPosition) { case Position.Left: tbl.Rows.Add(new TableRow()); tbl.Rows[0].Cells.Add(new TableCell()); tbl.Rows[0].Cells.Add(new TableCell()); break; case Position.Top: tbl.Rows.Add(new TableRow()); tbl.Rows[0].Cells.Add(new TableCell()); tbl.Rows.Add(new TableRow()); tbl.Rows[1].Cells.Add(new TableCell()); break; case Position.Right: tbl.Rows.Add(new TableRow()); tbl.Rows[0].Cells.Add(new TableCell()); tbl.Rows[0].Cells.Add(new TableCell()); break; case Position.Bottom: tbl.Rows.Add(new TableRow()); tbl.Rows[0].Cells.Add(new TableCell()); tbl.Rows.Add(new TableRow()); tbl.Rows[1].Cells.Add(new TableCell()); break; default: Debug.Assert(false); break; } // Return results return tbl; } #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 { EnsureChildControls(); return m_txt.CssClass; } set { Debug.Assert(value != null, "Warning: TextboxCssClass property is null!"); if (value != null) { EnsureChildControls(); m_txt.CssClass = 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 { EnsureChildControls(); return m_txt.ReadOnly; } set { EnsureChildControls(); m_txt.ReadOnly = 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)] [NotifyParentProperty(true)] public string TextboxText { get { EnsureChildControls(); return m_txt.Text; } set { Debug.Assert(value != null, "Warning: TextboxText property is null!"); if (value != null) { EnsureChildControls(); m_txt.Text = value; } 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 { EnsureChildControls(); return m_txt.MaxLength; } set { EnsureChildControls(); m_txt.MaxLength = value; } } #endregion } } Steven:
I have made some of the modifications you mentionned, such as moving code out of the Render method, and into the CreateChildControls() method. I've also pushed some code into OnPreRender(), rather than using the private method SetRunTimeProperties(). For testing purposes, I've also disabled the designer altogether (I only implemented it to allow SmartTags support). As to the properties not being stored in a local field and persisted into ViewState, I access them directly because the child controls themselves persist this information to ViewState. If I also added my 'TextboxText' property to ViewState, I would essentially be adding the same piece of information twice. In the parent class (SupportFormLabelledControl), I do place all custom (unique) variables in ViewState. Unfortunately, after making some of the changes you mentionned, I still have the same problem. When I make a change to any of my custom properties (such as TextboxText in this class, or LabelText in the parent class), the changes are added to the underlying Html code and appear at RunTime, but are never reflected in DesignMode, make the controls almost useless for the developers who will use them. I don't believe that it is mandatory to make a designer for every custom control, just to update properties at DesignTime, is it? (That seems like a lot of work for something that should be simple?). I suspect the problem is more than I am doing something in the wrong place, and so the properties are not being updated, or not 'UpdateMyPropertiesAnReRender' sort of event is being fired, etc. I'm really terribly behing schedule on finishing these controls, but just can't find the problem. (This is the first problem I've really had to go to the forums for, since I couldn't find any solutions through Google.) Any help you can offer will really be enourmously appreciated. The full updated code for one of the controls is located below. If you would like the parent class let me know. Thank you again for your help on this. 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 CompanyName.EEE.Web.UI.FormControls { /// <summary> /// An AJAX enabled TextBox control, which automatically applies the CompanyName style guide to its appearance. /// </summary> /// <seealso cref="T:SupportTextBoxDesigner"/> /// <seealso cref="T:SupportTextBoxActionList"/> // ToDo: Restore Designer // [Designer(typeof(SupportTextBoxDesigner))] [DefaultProperty("Text")] [DefaultEvent("TextChanged")] [ToolboxData("<{0}:SupportTextBox runat=server></{0}:SupportTextBox>")] public class SupportTextBox : SupportFormLabelledControl, INamingContainer { #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) { // Call base Load method base.OnLoad(e); EnsureChildControls(); } /// <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 Table tbl = new Table(); m_txt = new CallbackTextBox(); m_lbl = new CallbackLabel(); m_icn = new IconPopupControl(); // Register any events associated with dependant controls m_txt.TextChanged += new EventHandler(RaiseTextChanged); // Create table object and format it through relevant method tbl = CreateTable(this.LabelPosition); // Add table to the control collection Controls.Add(tbl); // Add controls to the table control collection switch (this.LabelPosition) { case Position.Left: tbl.Rows[0].Cells[0].Controls.Add(m_lbl); tbl.Rows[0].Cells[1].Controls.Add(m_txt); if (this.Required) { tbl.Rows[0].Cells[1].Controls.Add(m_icn); } // Set relevant design properties tbl.Rows[0].Cells[0].Width = new Unit(this.LabelWidth.ToString()); break; case Position.Top: tbl.Rows[0].Cells[0].Controls.Add(m_lbl); tbl.Rows[1].Cells[0].Controls.Add(m_txt); if (this.Required) { tbl.Rows[1].Cells[0].Controls.Add(m_icn); } // Set relevant design properties tbl.Rows[0].Cells[0].Width = new Unit(this.LabelWidth.ToString()); break; case Position.Right: tbl.Rows[0].Cells[0].Controls.Add(m_txt); if (this.Required) { tbl.Rows[0].Cells[0].Controls.Add(m_icn); } tbl.Rows[0].Cells[1].Controls.Add(m_lbl); // Set relevant design properties tbl.Rows[0].Cells[1].Width = new Unit(this.LabelWidth.ToString()); break; case Position.Bottom: tbl.Rows[0].Cells[0].Controls.Add(m_lbl); tbl.Rows[1].Cells[0].Controls.Add(m_txt); if (this.Required) { tbl.Rows[1].Cells[1].Controls.Add(m_icn); } // Set relevant design properties tbl.Rows[0].Cells[0].Width = new Unit(this.LabelWidth.ToString()); break; default: Debug.Assert(false); break; } // Call base method base.CreateChildControls(); } /// <summary> /// Raises the <see cref="E:System.Web.UI.Control.PreRender"></see> event. /// </summary> /// <param name="e">An <see cref="T:System.EventArgs"></see> object that contains the event data.</param> protected override void OnPreRender(EventArgs e) { base.OnPreRender(e); // 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; } /// <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(); // Create temporary HtmlTextWriter placeholder StringBuilder stringBuilder = new StringBuilder(); StringWriter stringWriter = new StringWriter(stringBuilder); HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter); // Render child controls RenderChildren(htmlWriter); // 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 RaiseTextChanged(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> /// Creates the table that will hold the relevant controls. /// </summary> /// <param name="labelPosition">The label position, which is used to /// determine how the table should be arranged.</param> /// <returns>A Table object</returns> private Table CreateTable(Position labelPosition) { Table tbl = new Table(); // Set basic table properties tbl.BorderStyle = BorderStyle.None; tbl.BorderWidth = 0; // Format table according to label position switch (labelPosition) { case Position.Left: tbl.Rows.Add(new TableRow()); tbl.Rows[0].Cells.Add(new TableCell()); tbl.Rows[0].Cells.Add(new TableCell()); break; case Position.Top: tbl.Rows.Add(new TableRow()); tbl.Rows[0].Cells.Add(new TableCell()); tbl.Rows.Add(new TableRow()); tbl.Rows[1].Cells.Add(new TableCell()); break; case Position.Right: tbl.Rows.Add(new TableRow()); tbl.Rows[0].Cells.Add(new TableCell()); tbl.Rows[0].Cells.Add(new TableCell()); break; case Position.Bottom: tbl.Rows.Add(new TableRow()); tbl.Rows[0].Cells.Add(new TableCell()); tbl.Rows.Add(new TableRow()); tbl.Rows[1].Cells.Add(new TableCell()); break; default: Debug.Assert(false); break; } // Return results return tbl; } #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 { EnsureChildControls(); return m_txt.CssClass; } set { Debug.Assert(value != null, "Warning: TextboxCssClass property is null!"); if (value != null) { EnsureChildControls(); m_txt.CssClass = 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 { EnsureChildControls(); return m_txt.ReadOnly; } set { EnsureChildControls(); m_txt.ReadOnly = 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)] [NotifyParentProperty(true)] public string TextboxText { get { EnsureChildControls(); return m_txt.Text; } set { Debug.Assert(value != null, "Warning: TextboxText property is null!"); if (value != null) { EnsureChildControls(); m_txt.Text = value; } 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 { EnsureChildControls(); return m_txt.MaxLength; } set { EnsureChildControls(); m_txt.MaxLength = value; } } #endregion } } I solved the problem by adding the following code to the Designer class.
Thanks for your help on this. /// <summary> /// Gets the HTML that is used to represent the control at design time. /// </summary> /// <returns> /// The HTML that is used to represent the control at design time. /// </returns> public override string GetDesignTimeHtml() { // ToDo: Change type SupportTextBox txt = this.Component as SupportTextBox; // Create temporary HtmlTextWriter placeholder StringBuilder stringBuilder = new StringBuilder(); StringWriter stringWriter = new StringWriter(stringBuilder); HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter); // Render control txt.RenderControl(htmlWriter); return stringBuilder.ToString(); } That's cool Man!
Yes, for design-time html representation ,we are recommended to make use of the GetDesignTimeHtml method of the designer. Glad that you've overcome the problem. Wish you good luck continually... Regards, 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: Problem Solved <ChristophePeillet@nospam.nospam>| thread-index: AcYV5yv83w0iuM2jRoCrkfkXXcw1NA== | X-WBNR-Posting-Host: 193.172.19.20 | From: =?Utf-8?B?Q2hyaXN0b3BoZSBQZWlsbGV0?= | References: <0CFC74DF-20E5-4DAF-A747-CB79A4D59***@microsoft.com> <4766EEC0-A1DB-4443-ACF1-17956E16B***@microsoft.com> <wYT0NyaFGHA.***@TK2MSFTNGXA02.phx.gbl> Show quoteHide quote | Subject: Problem Solved microsoft.public.dotnet.framework.aspnet.webcontrols:32365| Date: Tue, 10 Jan 2006 05:10:04 -0800 | Lines: 25 | Message-ID: <9BC6DD4B-274D-4DDE-A47F-C0A21CC23***@microsoft.com> | 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 Show quoteHide quote | X-Tomcat-NG: microsoft.public.dotnet.framework.aspnet.webcontrols | | I solved the problem by adding the following code to the Designer class. | Thanks for your help on this. | | /// <summary> | /// Gets the HTML that is used to represent the control at design | time. | /// </summary> | /// <returns> | /// The HTML that is used to represent the control at design time. | /// </returns> | public override string GetDesignTimeHtml() | { | // ToDo: Change type | SupportTextBox txt = this.Component as SupportTextBox; | | // Create temporary HtmlTextWriter placeholder | StringBuilder stringBuilder = new StringBuilder(); | StringWriter stringWriter = new StringWriter(stringBuilder); | HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter); | | // Render control | txt.RenderControl(htmlWriter); | | return stringBuilder.ToString(); | } |
Hide Menu Items Based On Roles
Panel Syntax TypeConverter Question ButtonColumn and EditCommandColumn don't work together as expected in DataGrid Dynamically show different web controls ASP.NET 2.0 sort DataList without query again multiple itemtemplates datalist Dynamically changing LinkButton properties Strange Results From FillEllipse Expose childcontrols |
|||||||||||||||||||||||