3
votes

I would like to validate a text field when the user is typing. Initially the text is empty. The validation rules are: 1 It's number only. 2 It's greater than 0 and less than 5. Following is the code in xmal.

 <TextBox Grid.Column="1" HorizontalAlignment="Left" Style="{StaticResource textBoxInError}" Name="txtQuantity" Margin="70,0,0,0" Width="70">
   <TextBox.Text>
     <Binding RelativeSource="{RelativeSource Mode=Self}" Path="Text" UpdateSourceTrigger="PropertyChanged">
       <Binding.ValidationRules>                                            
         <ValidationRules:PositiveIntegerRule Min="1" Max="5"></ValidationRules:PositiveIntegerRule>
       </Binding.ValidationRules>
     </Binding>
   </TextBox.Text>
 </TextBox>

My validation class is as follows(Please ignore the Chinese characters, it's the error message.):

 class PositiveIntegerRule : ValidationRule
{
    public ushort Max { get; set; }
    public ushort Min { get; set; }

    public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
    {
       ushort tmp = 0;
        try
        {
            if (value != null && !String.IsNullOrEmpty(value.ToString()))
            {
                tmp = ushort.Parse(value.ToString());
            }
            else
            {
                return new ValidationResult(false,"数值不能为空");
            }
        }
        catch (Exception e)
        {
            return new ValidationResult(false, "含有不合法字符");
        }

        if(tmp < Min || tmp > Max)
        {
            return new ValidationResult(false,string.Format("超出数值范围:最大值为{0},最小值为{1}",Max,Min));
        }
        else
        {
            return new ValidationResult(true,null);
        }
    }
}

The problem is when I run this wpf application, as long as the I type in a valid value, then it throw stack overflow exception. Method ValidationResult was called infinitely. While if the I type in a invalid value, the ValidationResult method would be called only once. But the style which for the invalidate value defined in resource wouldn't be applied.

I think the cause of this problem is using RelativeSource="{RelativeSource Mode=Self and UpdateSourceTrigger="PropertyChanged" at the same time. Source and destination are point to the same thing. So they will update each other infinitely. I even tried different binding mode to OneWayToSource, it still doesn't work.

  1. Could anybody here explain me what really happen when I use RelativeSource="{RelativeSource Mode=Self}" and UpdateSourceTrigger="PropertyChanged" together.
  2. I don't understand why the valid value cause infinite loop, but invalid value doesn't. Is that because if the method Validate returns new ValidationResult(false,xxx), then somewhere inside .net framework will throw an exception which stops the program running, then no infinite loop happen. While the valid value is on the opposite.
  3. Why I got an stack overflow exception rather than keep calling Validate method like keeping call CanExecute method.

Many thanks

I just added the call stack:

>   JieMeiTaoInventoryManager.exe!JieMeiTaoInventoryManager.ValidationRules.PositiveIntegerRule.Validate(object value, System.Globalization.CultureInfo cultureInfo) Line 16    C#
PresentationFramework.dll!System.Windows.Data.BindingExpressionBase.Validate(object value, System.Windows.Controls.ValidationStep validationStep) + 0x19a bytes 
PresentationFramework.dll!System.Windows.Data.BindingExpression.Validate(object value, System.Windows.Controls.ValidationStep validationStep) + 0x18 bytes  
PresentationFramework.dll!System.Windows.Data.BindingExpressionBase.UpdateValue() + 0x2e bytes  
PresentationFramework.dll!System.Windows.Data.BindingExpression.Update(bool synchronous) + 0x4f bytes   
PresentationFramework.dll!System.Windows.Data.BindingExpressionBase.Dirty() + 0x30 bytes    
PresentationFramework.dll!System.Windows.Data.BindingExpression.SetValue(System.Windows.DependencyObject d, System.Windows.DependencyProperty dp, object value) + 0x27 bytes    
WindowsBase.dll!System.Windows.DependencyObject.SetValueCommon(System.Windows.DependencyProperty dp, object value, System.Windows.PropertyMetadata metadata, bool coerceWithDeferredReference, bool coerceWithCurrentValue, System.Windows.OperationType operationType, bool isInternal) + 0x3c7 bytes  
PresentationFramework.dll!MS.Internal.Data.PropertyPathWorker.SetValue(object item, object value) + 0x171 bytes 
PresentationFramework.dll!MS.Internal.Data.ClrBindingWorker.UpdateValue(object value) + 0xa3 bytes  
PresentationFramework.dll!System.Windows.Data.BindingExpression.UpdateSource(object value) + 0x99 bytes 
PresentationFramework.dll!System.Windows.Data.BindingExpressionBase.UpdateValue() + 0x66 bytes  
PresentationFramework.dll!System.Windows.Data.BindingExpression.Update(bool synchronous) + 0x4f bytes   
PresentationFramework.dll!System.Windows.Data.BindingExpressionBase.Dirty() + 0x30 bytes    
PresentationFramework.dll!System.Windows.Data.BindingExpression.SetValue(System.Windows.DependencyObject d, System.Windows.DependencyProperty dp, object value) + 0x27 bytes    
WindowsBase.dll!System.Windows.DependencyObject.SetValueCommon(System.Windows.DependencyProperty dp, object value, System.Windows.PropertyMetadata metadata, bool coerceWithDeferredReference, bool coerceWithCurrentValue, System.Windows.OperationType operationType, bool isInternal) + 0x3c7 bytes  
WindowsBase.dll!System.Windows.DependencyObject.SetCurrentDeferredValue(System.Windows.DependencyProperty dp, System.Windows.DeferredReference deferredReference) + 0x29 bytes  
PresentationFramework.dll!System.Windows.Controls.TextBox.OnTextContainerChanged(object sender, System.Windows.Documents.TextContainerChangedEventArgs e) + 0xa7 bytes  
PresentationFramework.dll!System.Windows.Documents.TextContainer.EndChange(bool skipEvents) + 0xd9 bytes    
PresentationFramework.dll!System.Windows.Documents.TextContainer.System.Windows.Documents.ITextContainer.EndChange(bool skipEvents) + 0xb bytes 
PresentationFramework.dll!System.Windows.Documents.TextRangeBase.EndChange(System.Windows.Documents.ITextRange thisRange, bool disableScroll, bool skipEvents) + 0x77 bytes 
PresentationFramework.dll!System.Windows.Documents.TextRange.System.Windows.Documents.ITextRange.EndChange(bool disableScroll, bool skipEvents) + 0x15 bytes    
PresentationFramework.dll!System.Windows.Documents.TextRange.ChangeBlock.System.IDisposable.Dispose() + 0x15 bytes  
PresentationFramework.dll!System.Windows.Documents.TextEditorTyping.DoTextInput(System.Windows.Documents.TextEditor This, string textData, bool isInsertKeyToggled, bool acceptControlCharacters) + 0x1b2 bytes 
PresentationFramework.dll!System.Windows.Documents.TextEditorTyping.TextInputItem.Do() + 0x20 bytes 
PresentationFramework.dll!System.Windows.Documents.TextEditorTyping.ScheduleInput(System.Windows.Documents.TextEditor This, System.Windows.Documents.TextEditorTyping.InputItem item) + 0x2f bytes  
PresentationFramework.dll!System.Windows.Documents.TextEditorTyping.OnTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e) + 0x16c bytes   
PresentationFramework.dll!System.Windows.Controls.Primitives.TextBoxBase.OnTextInput(System.Windows.Input.TextCompositionEventArgs e) + 0x35 bytes  
PresentationCore.dll!System.Windows.UIElement.OnTextInputThunk(object sender, System.Windows.Input.TextCompositionEventArgs e) + 0x6f bytes 
PresentationCore.dll!System.Windows.Input.TextCompositionEventArgs.InvokeEventHandler(System.Delegate genericHandler, object genericTarget) + 0x31 bytes    
PresentationCore.dll!System.Windows.RoutedEventArgs.InvokeHandler(System.Delegate handler, object target) + 0x29 bytes  
PresentationCore.dll!System.Windows.RoutedEventHandlerInfo.InvokeHandler(object target, System.Windows.RoutedEventArgs routedEventArgs) + 0x3e bytes    
PresentationCore.dll!System.Windows.EventRoute.InvokeHandlersImpl(object source, System.Windows.RoutedEventArgs args, bool reRaised) + 0xbe bytes   
PresentationCore.dll!System.Windows.UIElement.RaiseEventImpl(System.Windows.DependencyObject sender, System.Windows.RoutedEventArgs args) + 0x79 bytes  
PresentationCore.dll!System.Windows.UIElement.RaiseTrustedEvent(System.Windows.RoutedEventArgs args) + 0x41 bytes   
PresentationCore.dll!System.Windows.UIElement.RaiseEvent(System.Windows.RoutedEventArgs args, bool trusted) + 0x2c bytes    
PresentationCore.dll!System.Windows.Input.InputManager.ProcessStagingArea() + 0x1ff bytes   
PresentationCore.dll!System.Windows.Input.InputManager.ProcessInput(System.Windows.Input.InputEventArgs input) + 0x45 bytes 
PresentationCore.dll!System.Windows.Input.TextCompositionManager.UnsafeCompleteComposition(System.Windows.Input.TextComposition composition) + 0x7e bytes   
PresentationCore.dll!System.Windows.Input.TextCompositionManager.PostProcessInput(object sender, System.Windows.Input.ProcessInputEventArgs e) + 0x41d bytes    
PresentationCore.dll!System.Windows.Input.InputManager.RaiseProcessInputEventHandlers(System.Windows.Input.ProcessInputEventHandler postProcessInput, System.Windows.Input.ProcessInputEventArgs processInputEventArgs) + 0x9d bytes    
PresentationCore.dll!System.Windows.Input.InputManager.ProcessStagingArea() + 0x23b bytes   
PresentationCore.dll!System.Windows.Input.InputManager.ProcessInput(System.Windows.Input.InputEventArgs input) + 0x45 bytes 
PresentationCore.dll!System.Windows.Input.TextCompositionManager.UnsafeStartComposition(System.Windows.Input.TextComposition composition) + 0x74 bytes  
PresentationCore.dll!System.Windows.Input.TextCompositionManager.PostProcessInput(object sender, System.Windows.Input.ProcessInputEventArgs e) + 0x6ca bytes    
PresentationCore.dll!System.Windows.Input.InputManager.RaiseProcessInputEventHandlers(System.Windows.Input.ProcessInputEventHandler postProcessInput, System.Windows.Input.ProcessInputEventArgs processInputEventArgs) + 0x9d bytes    
PresentationCore.dll!System.Windows.Input.InputManager.ProcessStagingArea() + 0x23b bytes   
PresentationCore.dll!System.Windows.Input.InputManager.ProcessInput(System.Windows.Input.InputEventArgs input) + 0x45 bytes 
PresentationCore.dll!System.Windows.Input.InputProviderSite.ReportInput(System.Windows.Input.InputReport inputReport) + 0x62 bytes  
PresentationCore.dll!System.Windows.Interop.HwndKeyboardInputProvider.ProcessTextInputAction(System.IntPtr hwnd, MS.Internal.Interop.WindowMessage msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) + 0x189 bytes 
PresentationCore.dll!System.Windows.Interop.HwndSource.OnPreprocessMessage(object param) + 0x2c6 bytes  
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) + 0x53 bytes 
WindowsBase.dll!MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(object source, System.Delegate method, object args, int numArgs, System.Delegate catchHandler) + 0x42 bytes    
WindowsBase.dll!System.Windows.Threading.Dispatcher.InvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, int numArgs) + 0xb4 bytes    
PresentationCore.dll!System.Windows.Interop.HwndSource.OnPreprocessMessageThunk(ref System.Windows.Interop.MSG msg, ref bool handled) + 0xc6 bytes  
PresentationCore.dll!System.Windows.Interop.HwndSource.WeakEventPreprocessMessage.OnPreprocessMessage(ref System.Windows.Interop.MSG msg, ref bool handled) + 0x35 bytes    
WindowsBase.dll!System.Windows.Interop.ComponentDispatcherThread.RaiseThreadMessage(ref System.Windows.Interop.MSG msg) + 0x3d bytes    
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame frame) + 0xaa bytes  
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame frame) + 0x49 bytes  
PresentationFramework.dll!System.Windows.Window.ShowHelper(object booleanBox) + 0x181 bytes 
PresentationFramework.dll!System.Windows.Window.Show() + 0x61 bytes 
PresentationFramework.dll!System.Windows.Window.ShowDialog() + 0x2d0 bytes  
JieMeiTaoInventoryManager.exe!JieMeiTaoInventoryManager.MainWindow.NewItemCommandBinding_Executed(object sender, System.Windows.Input.ExecutedRoutedEventArgs e) Line 291 + 0xd bytes   C#
PresentationCore.dll!System.Windows.Input.CommandBinding.OnExecuted(object sender, System.Windows.Input.ExecutedRoutedEventArgs e) + 0x63 bytes 
PresentationCore.dll!System.Windows.Input.CommandManager.ExecuteCommandBinding(object sender, System.Windows.Input.ExecutedRoutedEventArgs e, System.Windows.Input.CommandBinding commandBinding) + 0x98 bytes  
PresentationCore.dll!System.Windows.Input.CommandManager.FindCommandBinding(System.Windows.Input.CommandBindingCollection commandBindings, object sender, System.Windows.RoutedEventArgs e, System.Windows.Input.ICommand command, bool execute) + 0x10a bytes  
PresentationCore.dll!System.Windows.Input.CommandManager.FindCommandBinding(object sender, System.Windows.RoutedEventArgs e, System.Windows.Input.ICommand command, bool execute) + 0x1a0 bytes 
PresentationCore.dll!System.Windows.Input.CommandManager.OnExecuted(object sender, System.Windows.Input.ExecutedRoutedEventArgs e) + 0x26 bytes 
PresentationCore.dll!System.Windows.UIElement.OnExecutedThunk(object sender, System.Windows.Input.ExecutedRoutedEventArgs e) + 0x59 bytes   
PresentationCore.dll!System.Windows.Input.ExecutedRoutedEventArgs.InvokeEventHandler(System.Delegate genericHandler, object target) + 0x3e bytes    
PresentationCore.dll!System.Windows.RoutedEventArgs.InvokeHandler(System.Delegate handler, object target) + 0x29 bytes  
PresentationCore.dll!System.Windows.RoutedEventHandlerInfo.InvokeHandler(object target, System.Windows.RoutedEventArgs routedEventArgs) + 0x3e bytes    
PresentationCore.dll!System.Windows.EventRoute.InvokeHandlersImpl(object source, System.Windows.RoutedEventArgs args, bool reRaised) + 0xbe bytes   
PresentationCore.dll!System.Windows.UIElement.RaiseEventImpl(System.Windows.DependencyObject sender, System.Windows.RoutedEventArgs args) + 0x79 bytes  
PresentationCore.dll!System.Windows.UIElement.RaiseTrustedEvent(System.Windows.RoutedEventArgs args) + 0x41 bytes   
PresentationCore.dll!System.Windows.UIElement.RaiseEvent(System.Windows.RoutedEventArgs args, bool trusted) + 0x2c bytes    
PresentationCore.dll!System.Windows.Input.RoutedCommand.ExecuteImpl(object parameter, System.Windows.IInputElement target, bool userInitiated) + 0x111 bytes    
PresentationCore.dll!System.Windows.Input.RoutedCommand.ExecuteCore(object parameter, System.Windows.IInputElement target, bool userInitiated) + 0x5b bytes 
PresentationCore.dll!System.Windows.Input.CommandManager.TranslateInput(System.Windows.IInputElement targetElement, System.Windows.Input.InputEventArgs inputEventArgs) + 0x3df bytes   
PresentationCore.dll!System.Windows.UIElement.OnKeyDownThunk(object sender, System.Windows.Input.KeyEventArgs e) + 0x67 bytes   
PresentationCore.dll!System.Windows.Input.KeyEventArgs.InvokeEventHandler(System.Delegate genericHandler, object genericTarget) + 0x34 bytes    
PresentationCore.dll!System.Windows.RoutedEventArgs.InvokeHandler(System.Delegate handler, object target) + 0x29 bytes  
PresentationCore.dll!System.Windows.RoutedEventHandlerInfo.InvokeHandler(object target, System.Windows.RoutedEventArgs routedEventArgs) + 0x3e bytes    
PresentationCore.dll!System.Windows.EventRoute.InvokeHandlersImpl(object source, System.Windows.RoutedEventArgs args, bool reRaised) + 0xbe bytes   
PresentationCore.dll!System.Windows.UIElement.RaiseEventImpl(System.Windows.DependencyObject sender, System.Windows.RoutedEventArgs args) + 0x79 bytes  
PresentationCore.dll!System.Windows.UIElement.RaiseTrustedEvent(System.Windows.RoutedEventArgs args) + 0x41 bytes   
PresentationCore.dll!System.Windows.UIElement.RaiseEvent(System.Windows.RoutedEventArgs args, bool trusted) + 0x2c bytes    
PresentationCore.dll!System.Windows.Input.InputManager.ProcessStagingArea() + 0x1ff bytes   
PresentationCore.dll!System.Windows.Input.InputManager.ProcessInput(System.Windows.Input.InputEventArgs input) + 0x45 bytes 
PresentationCore.dll!System.Windows.Input.InputProviderSite.ReportInput(System.Windows.Input.InputReport inputReport) + 0x62 bytes  
PresentationCore.dll!System.Windows.Interop.HwndKeyboardInputProvider.ReportInput(System.IntPtr hwnd, System.Windows.Input.InputMode mode, int timestamp, System.Windows.Input.RawKeyboardActions actions, int scanCode, bool isExtendedKey, bool isSystemKey, int virtualKey) + 0x101 bytes    
PresentationCore.dll!System.Windows.Interop.HwndKeyboardInputProvider.ProcessKeyAction(ref System.Windows.Interop.MSG msg, ref bool handled) + 0xf4 bytes   
PresentationCore.dll!System.Windows.Interop.HwndSource.CriticalTranslateAccelerator(ref System.Windows.Interop.MSG msg, System.Windows.Input.ModifierKeys modifiers) + 0x8f bytes   
PresentationCore.dll!System.Windows.Interop.HwndSource.OnPreprocessMessage(object param) + 0x106 bytes  
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) + 0x53 bytes 
WindowsBase.dll!MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(object source, System.Delegate method, object args, int numArgs, System.Delegate catchHandler) + 0x42 bytes    
WindowsBase.dll!System.Windows.Threading.Dispatcher.InvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, int numArgs) + 0xb4 bytes    
PresentationCore.dll!System.Windows.Interop.HwndSource.OnPreprocessMessageThunk(ref System.Windows.Interop.MSG msg, ref bool handled) + 0xc6 bytes  
PresentationCore.dll!System.Windows.Interop.HwndSource.WeakEventPreprocessMessage.OnPreprocessMessage(ref System.Windows.Interop.MSG msg, ref bool handled) + 0x35 bytes    
WindowsBase.dll!System.Windows.Interop.ComponentDispatcherThread.RaiseThreadMessage(ref System.Windows.Interop.MSG msg) + 0x3d bytes    
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame frame) + 0xaa bytes  
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame frame) + 0x49 bytes  
PresentationFramework.dll!System.Windows.Application.RunDispatcher(object ignore) + 0x5b bytes  
PresentationFramework.dll!System.Windows.Application.RunInternal(System.Windows.Window window) + 0x74 bytes 
PresentationFramework.dll!System.Windows.Application.Run(System.Windows.Window window) + 0x2b bytes 
PresentationFramework.dll!System.Windows.Application.Run() + 0x1b bytes 
JieMeiTaoInventoryManager.exe!JieMeiTaoInventoryManager.App.Main() + 0x5e bytes C#
[Native to Managed Transition]  
[Managed to Native Transition]  
mscorlib.dll!System.AppDomain.ExecuteAssembly(string assemblyFile, System.Security.Policy.Evidence assemblySecurity, string[] args) + 0x6d bytes    
Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() + 0x2a bytes  
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state) + 0x63 bytes   
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool ignoreSyncCtx) + 0xb0 bytes    
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x2c bytes    
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x44 bytes   
[Native to Managed Transition]  

Update: I noticed that following lines are repeatedly called every time my program hit Validate method.

    PresentationFramework.dll!MS.Internal.Data.PropertyPathWorker.SetValue(object item, object value) + 0x171 bytes 
PresentationFramework.dll!MS.Internal.Data.ClrBindingWorker.UpdateValue(object value) + 0xa3 bytes  
PresentationFramework.dll!System.Windows.Data.BindingExpression.UpdateSource(object value) + 0x99 bytes 
PresentationFramework.dll!System.Windows.Data.BindingExpressionBase.UpdateValue() + 0x66 bytes  
PresentationFramework.dll!System.Windows.Data.BindingExpression.Update(bool synchronous) + 0x4f bytes   
PresentationFramework.dll!System.Windows.Data.BindingExpressionBase.Dirty() + 0x30 bytes    
PresentationFramework.dll!System.Windows.Data.BindingExpression.SetValue(System.Windows.DependencyObject d, System.Windows.DependencyProperty dp, object value) + 0x27 bytes    
WindowsBase.dll!System.Windows.DependencyObject.SetValueCommon(System.Windows.DependencyProperty dp, object value, System.Windows.PropertyMetadata metadata, bool coerceWithDeferredReference, bool coerceWithCurrentValue, System.Windows.OperationType operationType, bool isInternal) + 0x3c7 bytes  

Update 2 If my Validate method return new ValidationResult(false,xxx), then infinite loop wouldn't happen. I am wondering if ValidationResult(false,xxx) trigger an event somewhere which stop the loop?

1
What sequence of method calls results in StackOverflowException? Please post the repeating sequence of stack trace calls. - Karel Frajták
I have added the call stack. In this case I typed in a valid value 2 which cause stack overflow exception. - Tianze
I don't see any repeating calls in stack trace. Here are my suggestions - remove the RelativeSource from Binding element, move the validation rules into view model (more maintainable), use ushort.TryParsr, do more debugging. - Karel Frajták
It probably has something to do with the fact you're binding the TextBox.Text property to itself, so changing the Text is causing an infinite loop as it triggers a change notification, which re-evaluates the binding, which updates the values, which triggers a change notification, which re-evaluates the binding, etc. - Rachel
Hi Karel, the reason you couldn't see any repeating calls is I got the call stack when I was debugging, so the program stopped at the point when Validate method was called. I got different call stacks after the method was called a few times. I compared the call stacks and I noticed that every time the method was hit, a few methods were called repeatedly. I put these lines in my update section. - Tianze

1 Answers

1
votes

Try with this validation (you must have an event) then make your other validation..if greater 0 and less than 5

private bool AreAllValidNumericChars(string str)
{
  foreach (char c in str)
  {
    if (c != '.')
    {
      if (!Char.IsNumber(c))
        return false;
    }
  }
  return true;
}

private void textBoxMs_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
  e.Handled = !AreAllValidNumericChars(e.Text) && isGreaterOrLess(e.Text);
}

public bool isGreaterOrLess(string text)
{
  int number = Convert.toInt32(text);
  if(number>0 && number<5)
  {
    return true;
  }
  else
  {
    return false
  }

}