Question

I need to make a custom TextBox, which takes text or numbers. After PostBack I want to check the value, and if it's not numbers - white a span behind TextBox with words "Not Digits!". I made a property Number, which checks the value, and if all ok - put it into viewstate, else, write string "Not Digits!". Here the code:

namespace NumericTextBoxLibraryV2
{
[DefaultProperty("Number")]
[ToolboxData("<{0}:NumericTextBox runat=server></{0}:NumericTextBox>")]
public class NumericTextBox : TextBox
{
    public override string Text
    {
        get
        {
            return base.Text;
        }
        set
        {
            base.Text = value;
            if(!Int32.TryParse(value, out number))
                notNumber = "Digits only!";
        }
    }

    [Bindable(true)]
    [Category("Appearance")]
    //[DefaultValue("")]
    //[Localizable(true)]
    public int Number
    {
        get
        {
            if(ViewState["Number"] == null)
            {
                ViewState["Number"] = 0;
            }
            number = (int)ViewState["Number"];
            return number;
        }

        set
        {
            Match match = Regex.Match(value.ToString(), @"^\d+$");
            if (match.Success)
            {
                ViewState["Number"] = value;
                notNumber = string.Empty;
            }
            else
            {
                notNumber = "Digits only!";
            }
        }
    }

    private int number;
    private string notNumber;

    protected override void Render(HtmlTextWriter writer)
    {
        writer.Write(@"<span>{0}&nbsp;</span><br />", notNumber);
        base.Render(writer);
    }

    protected override void RenderContents(HtmlTextWriter output)
    {
        output.Write(Number);
    }
}
}

The question: As you can see, I can get the value writen in TextBox only from Text property. Is there any way to write the code, which will set value not to Text, but to my property Number? And how to make shown not Text property but Number?

Was it helpful?

Solution

Yes, you need to override the TextBox's LoadPostData method, which actually comes from implementing IPostBackDataHandler. This happens early in the page lifecycle and actually from there the control gets its Text property.

There, you can jump in and get the value straight from the request params.

However, since you're extending the text box you will always have the text property. A clean version would imply extending Control and doing the input rendering yourself. You would drop the Text property altogether and keep only your Number property.

The code would be cleaner and a lot easier to read. But it implies a bit more work, of course. Note that in case you are extending Control directly, you need to implement IPostBackDataHandler. That interface basically tells the page that your control posts data back and it needs to be handled differently.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top