Hi,

I have a UserControl called NumericBox which is simply a UserControl with a single TextBox:
asp Code:
  1. <%@ Control Language="vb" AutoEventWireup="false" CodeBehind="NumericBox.ascx.vb" Inherits="F1TimeTrials.Controls.NumericBox" %>
  2.  
  3. <asp:TextBox runat="server" ID="txt" />
In the code-behind, I add some attributes to the textbox which handle some events such as OnKeyPress (with some javascript) to make sure the user can only enter numeric values. I don't think the javascript is relevant but I can post it if it is.


This works fine, I can put this control on my page and it will only allow numeric input. The next step is to use two kinds of validator controls: a RequiredFieldValidator and a RangeValidator, to ensure that the user has entered a value at all and that it is in the allowed range.

Both of these don't seem to work... The first problem was that my UserControl is not one of the controls the validators can validate, so I had to add a System.Web.UI.ValidationProperty attribute to my class. As far as I know this should have the name of the property that determines the value of the control, so that's exactly what I did:
vb.net Code:
  1. Namespace Controls
  2.  
  3.     <System.Web.UI.ValidationProperty("Value")> _
  4.     Public Class NumericBox
  5.         Inherits System.Web.UI.UserControl
  6.  
  7.         Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
  8.             Me.SetAttributes()
  9.         End Sub
  10.  
  11.         Public ReadOnly Property TextBox As TextBox
  12.             Get
  13.                 Return txt
  14.             End Get
  15.         End Property
  16.  
  17.         Private _AllowNegative As Boolean = False
  18.         Public Property AllowNegative() As Boolean
  19.             Get
  20.                 Return _AllowNegative
  21.             End Get
  22.             Set(ByVal value As Boolean)
  23.                 _AllowNegative = value
  24.             End Set
  25.         End Property
  26.  
  27.         Private _AllowDecimal As Boolean = False
  28.         Public Property AllowDecimal() As Boolean
  29.             Get
  30.                 Return _AllowDecimal
  31.             End Get
  32.             Set(ByVal value As Boolean)
  33.                 _AllowDecimal = value
  34.             End Set
  35.         End Property
  36.  
  37.         Public Property Width As Unit
  38.             Get
  39.                 Return txt.Width
  40.             End Get
  41.             Set(ByVal value As Unit)
  42.                 txt.Width = value
  43.             End Set
  44.         End Property
  45.  
  46.         Private Sub SetAttributes()
  47.             Dim strDecimal = Me.AllowDecimal.ToString.ToLower
  48.             Dim strNegative = Me.AllowNegative.ToString.ToLower
  49.  
  50.             txt.Attributes.Remove("onblur")
  51.             txt.Attributes.Remove("onkeyup")
  52.             txt.Attributes.Remove("onkeypress")
  53.             txt.Attributes.Add("onblur", String.Format("extractNumber(this, 2, {0});", strNegative))
  54.             txt.Attributes.Add("onkeyup", String.Format("extractNumber(this, 2, {0});", strNegative))
  55.             txt.Attributes.Add("onkeypress", String.Format("return blockNonNumbers(this, event, {0}, {1});", strDecimal, strNegative))
  56.         End Sub
  57.  
  58.         Public Property Value As Object
  59.             Get
  60.                 If txt.Text = String.Empty Then Return 0
  61.                 If Me.AllowDecimal Then Return Double.Parse(txt.Text)
  62.                 Return Integer.Parse(txt.Text)
  63.             End Get
  64.             Set(ByVal value As Object)
  65.                 If Me.AllowDecimal Then
  66.                     txt.Text = CDbl(value).ToString("0.00")
  67.                 Else
  68.                     txt.Text = value.ToString()
  69.                 End If
  70.             End Set
  71.         End Property
  72.  
  73.     End Class
  74. End Namespace
The Value property returns either the Double or Integer (based on whether AllowDecimal is true or false) equivalent of the text in the textbox 'txt'.
I let the System.Web.UI.ValidationProperty attribute point to this Value property, and now I can use both validators without warnings in the editor.

However, it does not seem to work during run-time.


Here's an example how I'm using it:
asp Code:
  1. <uc:NumericBox runat="server"
  2.                ID="numFrontWingAngle"
  3.                AllowDecimal="false"
  4.                AllowNegative="false"
  5.                Width="30px" />
  6. <asp:RequiredFieldValidator runat="server"
  7.                             ControlToValidate="numFrontWingAngle"
  8.                             ErrorMessage="* Cannot be empty."
  9.                             ForeColor="Red" />
  10. <asp:RangeValidator runat="server"
  11.                     ControlToValidate="numFrontWingAngle"
  12.                     MinimumValue="1"
  13.                     MaximumValue="11"
  14.                     ErrorMessage="* Range is 1-11."
  15.                     ForeColor="Red"
  16.                     Type="Integer"  />

It doesn't work. I can enter values outside the range 1-11, I can even leave it empty, the validators never show their warnings or stop the page from posting back (as they should, right?)


What is causing my problem? I thought the RequiredFieldValidator might not work because the Value is returned as 0 if the textbox is empty, but even then, 0 is outside the range 1-11 so at least the RangeValidator should complain?

Thanks!