Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to constrain a TextBox

How to set up a TextBox to get only certain values. e.g. DateTime input box with defined format settings.

like image 848
iLemming Avatar asked Dec 22 '22 10:12

iLemming


2 Answers

How about using the Binding Validation that comes with the WPF Framework.

Create a ValidationRule like so

public class DateFormatValidationRule : ValidationRule
{
  public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
  {
     var s = value as string;
     if (string.IsNullOrEmpty(s))
        return new ValidationResult(false, "Field cannot be blank");
     var match = Regex.Match(s, @"^\d{2}/\d{2}/\d{4}$");
     if (!match.Success)
        return new ValidationResult(false, "Field must be in MM/DD/YYYY format");
     DateTime date;
     var canParse = DateTime.TryParse(s, out date);
     if (!canParse)
        return new ValidationResult(false, "Field must be a valid datetime value");
     return new ValidationResult(true, null);
  }
}

Then add it to your binding in xaml as well as a style to handle when the field is invalid. (You can also use Validation.ErrorTemplate if you're inclined to completely change the control.) This one puts the ValidationResult text as a tooltip and the box to red.

    <TextBox x:Name="tb">
        <TextBox.Text>
            <Binding Path="PropertyThatIsBoundTo" UpdateSourceTrigger="PropertyChanged">
                <Binding.ValidationRules>
                    <val:DateFormatValidationRule/>
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>
        <TextBox.Style>
            <Style TargetType="{x:Type TextBox}">
                <Style.Triggers>
                    <Trigger Property="Validation.HasError" Value="true">
                        <Setter Property="ToolTip"
                                Value="{Binding RelativeSource={RelativeSource Self},
                            Path=(Validation.Errors)[0].ErrorContent}"/>
                        <Setter Property="Background" Value="Red"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </TextBox.Style>
    </TextBox>

A recommendation would be to take the style and put it into a resource dictionary so any textbox you want to have the same appearance when its own validation fails. Makes the XAML a lot cleaner too.

like image 101
statenjason Avatar answered Dec 26 '22 00:12

statenjason


http://www.codeproject.com/KB/WPF/wpfvalidation.aspx

<TextBox Text="{Binding Path=Name}" />

And a function. This one just checks the string has content. Yours will be more complex depending on the exact format you want to enforce:

public string Name
{
    get { return _name; }
    set
    {
        _name = value;
        if (String.IsNullOrEmpty(value))
        {
            throw new ApplicationException("Customer name is mandatory.");
        }
    }
}
like image 25
the.jxc Avatar answered Dec 25 '22 23:12

the.jxc