3
\$\begingroup\$

I have created a custom web server control that will have a bool property 'RenderAsLabel' so that I can convert TextBoxes to Labels, for read-only forms. I was wondering if there is any reason why this code should not be safe, or work as intended. Upon initial testing it seems fine, but I just want to make sure I'm not doing something that will end up causing issues.

namespace OrmControlLibrary
{
    [DefaultProperty("Text")]
    [ToolboxData("<{0}:OrmTextBox ID='' runat=server ></{0}:OrmTextBox>")]
    public class OrmTextBox : TextBox
    {
        private Label lbl;
        public virtual bool RenderAsLabel
        {
            get
            {
                if (ViewState["OrmTextBox"] == null)
                {
                    return false;
                }
                else
                {
                    return (bool)ViewState["OrmTextBox"];
                }
            }
            set
            {
                ViewState["OrmTextBox"] = value;
            }
        }

        protected override void Render(HtmlTextWriter w)
        {
            if (RenderAsLabel)
            {
                SetLabelProperties();
                lbl.RenderControl(w);
            }
            else
            {
                base.Render(w);
            }
        }

        private void SetLabelProperties()
        {
            lbl = new Label();
            lbl.ID = this.ID;
            lbl.CssClass = this.CssClass;
            lbl.Text = this.Text;
        }
    }
}
\$\endgroup\$
3
  • \$\begingroup\$ Is there a reason you can't just set the ReadOnly property to true? \$\endgroup\$
    – user33306
    Commented Jul 16, 2014 at 14:48
  • \$\begingroup\$ Yes, I want it to be a label, not a non-editable text box with grayed out text. I created this control in order to avoid the extra work of creating a label for each input, and showing or hiding each control based on whether the form should be displayed as read-only or not. \$\endgroup\$ Commented Jul 16, 2014 at 15:31
  • 1
    \$\begingroup\$ Have you considered creating a custom control that inherits from the base WebControl type instead of from TextBox? If your TextBox is sometimes a Label, then it is also sometimes NOT a textbox. Inheriting from WebControl and having your custom control have instances of a TextBox and a Label, then conditionally render each may make this more clear for future developers (and yourself). \$\endgroup\$
    – xDaevax
    Commented Jul 16, 2014 at 17:36

1 Answer 1

3
\$\begingroup\$

I would probably have a custom control that wrapped instances of the controls instead of directly inheriting from one of two possible controls, if that makes sense.

This approach leaves your code more open in the future and allows you to add additional features as part of your control (like validation controls for example) that conditionally become applied when the mode is set to a TextBox.

Here is what I came up with (this should be a run-able example):

using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace CustomControls.Web {

    [DesignTimeVisible(true)]
    [ToolboxData("<{0}:TextBoxLabel ID='' runat='server' />")]
    [DefaultProperty("Text")]
    public class TextBoxLabel : WebControl {

        #region --Instance Variables--

        private Label _ctlLabel;
        private TextBox _ctlTextBox;
        private TextBoxLabelModes _mode;
        private WebControl _renderedControl;
        private string _text;

        #endregion

        #region --Constructors--

        /// <summary>
        /// Creates a new instance of the TextBoxLabel class.
        /// </summary>
        public TextBoxLabel()
            : base() {
                _ctlLabel = new Label();
                _ctlTextBox = new TextBox();
                _mode = TextBoxLabelModes.Default;
                _renderedControl = null;
                _text = string.Empty;
        } // end constructor

        #endregion

        #region --Methods--

        protected override void CreateChildControls() {
            base.CreateChildControls();
            if (this._mode == TextBoxLabelModes.TextBox) {
                _renderedControl = this._ctlTextBox;
            } else {
                _renderedControl = this._ctlLabel;
            }
            _renderedControl.ID = this.ID;
        } // end method CreateChildControls

        public override void RenderControl(HtmlTextWriter writer) {
            _renderedControl.RenderControl(writer);
        } // end method RenderControl

        #endregion

        #region --Properties--

        [Category("Appearance")]
        public virtual TextBoxLabelModes ControlMode {
            get {
                return _mode;
            } set {
                _mode = value;
            }
        } // end property ControlMode

        [Category("Data")]
        public virtual string Text {
            get {
                return _text;
            } set {
                if (!string.IsNullOrWhiteSpace(value)) {
                    _text = value;
                    _ctlLabel.Text = value;
                    _ctlTextBox.Text = value;
                } // end if
            }
        } // end property Text

        #endregion

    } // end class TextBoxLabel

    public enum TextBoxLabelModes : int {

        Default = 0,

        Label = 1,

        TextBox = 2
    }

} // end namespace
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.