Home > Net >  Using RegularExpression as attribute in .NET
Using RegularExpression as attribute in .NET

Time:12-18

I am testing use of regular expression as attribute in my application, but it is simply not working.

public partial class MainWindow : Window
{
    [Required]
    [RegularExpression(@"^[\d] ")]
    public string number { get; set; }

    public MainWindow()
    {
        InitializeComponent();
        number = "sometext";
    }
 }

No error is being thrown and number accepts anything without caring for RegularExpression attribute.

How can I make number only to accept what is mentioned in regex? Usually I do validate in setter, but have learnt recently about attribute and wish to use it.

Thanks.

CodePudding user response:

Your binding source must implement the IDataErrorInfo interface. Then you can set the ValidatesOnDataErrors and NotifyOnValidationError propeties on the binding.

See a simplified example below.

A base class to handle property changes and validation.


internal abstract class ValidatedObservableBase : INotifyPropertyChanged, IDataErrorInfo
{
    public event PropertyChangedEventHandler PropertyChanged;

    public string this[string columnName]
    {
        get
        {
            var results = new List<ValidationResult>();
            var valid = Validator.TryValidateProperty(GetType().GetProperty(columnName)?.GetValue(this), new ValidationContext(this) { MemberName = columnName }, results);

            return valid ? null : results[0].ErrorMessage;
        }
    }

    public string Error
    {
        get => null;
    }

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

The model, derived from the above base class.


internal class Model : ValidatedObservableBase
{
    private string number;

    [Required(ErrorMessage = "Required error")]
    [RegularExpression(@"^[\d] ", ErrorMessage = "Regex error")]
    public string Number
    {
        get => number;
        set
        {
            number = value;
            OnPropertyChanged();
        }
    }
}

A simple view model to set as the window's DataContext.


internal class ViewModel
{
    public Model Model { get; set; } = new Model();
}

Lastly, the window.


<Window
    ...
    xmlns:local="clr-namespace:Demo"
    mc:Ignorable="d">
    <Window.DataContext>
        <local:ViewModel />
    </Window.DataContext>
    <StackPanel>
        <TextBox
            x:Name="TB"
            Margin="24,24,24,0"
            VerticalAlignment="Top"
            Text="{Binding Path=Model.Number, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnValidationError=True}" />
        <TextBlock
            Margin="24,4,24,24"
            Foreground="Red"
            Text="{Binding ElementName=TB, Path=(Validation.Errors)[0].ErrorContent}" />
    </StackPanel>
</Window>

demo

CodePudding user response:

Thanks for comments. I modified code with some information on this site. myTextbox is bind with number and am using validation attribute. But still this is accepting everything that I write in my textbox.

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        myTextBox.DataContext = this;         
    }

    [Required]
    [AcceptNumberAttribute]
    public string number { get; set; }        
 }

public sealed class AcceptNumberAttribute : ValidationAttribute

{

    public override bool IsValid(object value)
    {
        return new RegularExpressionAttribute(@"^[\d]$").IsValid(Convert.ToString(value).Trim());
    }

}

  • Related