Table of Contents

Data Validation

Eremex editors support the following approaches to data validation, which maintain correct data input, value checking and displaying errors for invalid data:

  • Masks — Allow you to specify a pattern that restricts data input by users in text editors.
  • Data validation at the editor level, using the BaseEditor.Validate event.
  • Data validation at the bound object level, using the DataAnnotation attributes and INotifyDataErrorInfo interface.

This topic provides more details on data validation in Eremex editors.

To learn about data validation in container controls, see the following topic:

Automatic Validation

Eremex editors support automatic validation of values that a user enters. The automatic validation checks an editor's value against a mask, if any. If the editor is bound to a property, the validation mechanism also does the following:

  • Checks DataAnnotation valdation attributes applied to the property.
  • Checks errors created with the INotifyDataErrorInfo interface.
  • Checks whether the entered value can be converted to the data type of the bound property.

Data validation is invoked in the following cases:

  • An editor's value is updated in code.
  • When an editor is about to lose focus.
  • A user types any character, provided that the BaseEdit.ValidateOnInput property is set to true (default value).
  • A user presses the Enter key, provided that the BaseEdit.ValidateOnInput option is set to false.

Force Data Validation

In specific cases, you may want to forcibly invoke the validation mechanism for an editor. Use the BaseEditor.DoValidate method for this purpose.

Data Validation at the Editor Level

'Validate' Event

The BaseEditor.Validate event allows you to perform data validation at the editor level in code-behind. The following event arguments are available:

  • ValidationEventArgs.Value — Gets the current value.
  • ValidationEventArgs.ErrorContent — Allows you to specify an error if the current value is invalid. If you leave the ErrorContent property set to null, the current value is considered valid.

Example - Verify that the entered value is a valid email address

The following example handles the BaseEditor.Validate event to check that the string entered in a Text Editor is a valid email address. The ValidateOnInput option set to true ensures that the validation is invoked whenever a character is pressed.

editors-validation-validate-event-example

<mxe:TextEditor x:Name="textEditor3" 
                ValidateOnInput="true"
                Validate="textEditorValidate"/>

private void textEditorValidate(object sender, Eremex.AvaloniaUI.Controls.Editors.ValidationEventArgs e)
{
    if(e.Value == null || !IsEmailAddress(e.Value.ToString()))
    {
        e.ErrorContent = "Please enter a valid e-mail address";
    }
}

bool IsEmailAddress(string email)
{
    Regex regex = new Regex(@"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$");
    Match match = regex.Match(email);
    return match.Success;
}

Data Validation at the Bound Object Level

Data Validation Using DataAnnotation Attributes

You can use DataAnnotations validation attributes (System.ComponentModel.DataAnnotations.ValidationAttribute descendants) to create a validation rule for a business object's property. When bound to this property, an Eremex editor automatically checks the data validity rule specified by this attribute.

The list below shows most common validation attributes:

  • CompareAttribute — Provides an attribute that compares two properties.
  • CustomValidationAttribute — Specifies a custom validation method that is used to validate a property or class instance.
  • MaxLengthAttribute — Specifies the maximum length of array or string data allowed in a property.
  • MinLengthAttribute — Specifies the minimum length of array or string data allowed in a property.
  • RangeAttribute — Specifies the numeric range constraints for the value of a data field.
  • RegularExpressionAttribute — Specifies that a data field value must match the specified regular expression.
  • RequiredAttribute — Specifies that a data field value is required.
  • StringLengthAttribute — Specifies the minimum and maximum length of characters that are allowed in a data field.

Example - Validate using 'RangeAttribute'

The following example uses the RangeAttribute attribute to ensure that a property's value is in the range between 10 and 100. An editor displays an error if the value is out of this range.

texteditor-validation-dataannotation-rangeattribute-example

<mxe:TextEditor x:Name="textEditor1" 
    Grid.Row="1" 
    HorizontalContentAlignment="Right" 
    EditorValue="{Binding Capacity}" />
public partial class MyViewModel : ObservableObject
{
    [ObservableProperty]
    [property: Range(10, 100, ErrorMessage = "Value for {0} must be between {1} and {2}.")]
    int capacity;
}

Data Validation Using 'INotifyDataErrorInfo' Interface

The System.ComponentModel.INotifyDataErrorInfo interface allows you to implement custom validation rules at the business object level. The interface supports synchronous and asynchronous validation, multiple errors per property, and cross-property errors.

Example - Implement 'INotifyDataErrorInfo' interface

The following example binds a Text Editor to the NickName property defined in the MainViewModel class. The MainViewModel class implements the INotifyDataErrorInfo interface that defines three validation rules for the NickName property. The Text Editor displays an error if the INotifyDataErrorInfo.GetErrors method returns an error(s) for the NickName property.

editors-validation-inotifydataerrorinfo-example

<mxe:TextEditor x:Name="textEditor2" EditorValue="{Binding NickName}"/>
public partial class MainViewModel : ObservableObject, INotifyDataErrorInfo
{
    private Dictionary<string, List<string>> propertyErrors = new Dictionary<string, List<string>>();

    [ObservableProperty]
    public string nickName;

    partial void OnNickNameChanged(string oldValue, string newValue)  => ValidateNickName();

    public bool HasErrors => propertyErrors.Any();

    public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;

    public IEnumerable GetErrors(string propertyName)
    {
        if (propertyErrors.ContainsKey(propertyName))
            return propertyErrors[propertyName];
        else
            return null;
    }

    private void RaiseErrorsChanged(string propertyName)
    {
        ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
    }

    private void ValidateNickName()
    {
        ClearErrors(nameof(NickName));

        if (string.IsNullOrEmpty(NickName))
            AddError(nameof(NickName), "Nick Name cannot be empty.");
        if (string.Equals(NickName, "user", StringComparison.OrdinalIgnoreCase))
            AddError(nameof(NickName), "Invalid Nick Name: 'user'");
        if (NickName == null || NickName?.Length <= 5)
            AddError(nameof(NickName), "The string is too short");
    }

    private void AddError(string propertyName, string error)
    {
        if (!propertyErrors.ContainsKey(propertyName))
            propertyErrors[propertyName] = new List<string>();

        if (!propertyErrors[propertyName].Contains(error))
        {
            propertyErrors[propertyName].Add(error);
            RaiseErrorsChanged(propertyName);
        }
    }

    private void ClearErrors(string propertyName)
    {
        if (propertyErrors.ContainsKey(propertyName))
        {
            propertyErrors.Remove(propertyName);
            RaiseErrorsChanged(propertyName);
        }
    }

    public MainViewModel()
    {
        //...
        NickName = "user";
    }
}

Indicate Errors

When an error occurs during data validation, the editor indicates the error as specified by the BaseEditor.ErrorShowMode property. Two error display modes are supported:

Show Built-in Error Icon and Tooltip

If the ErrorShowMode property is set to Inplace, an editor displays an error icon within the edit box. When a user hovers over the icon, a tooltip with an error description appears.

texteditor-errorshowmode-inplace

Show Error Below Editor

Set the ErrorShowMode property to Full to display an error description below the edit box. The inplace error icon is hidden in this case.

texteditor-errorshowmode-full

Set and Clear the Error Text

You can do one of the following to specify the error text:

  • Handle the BaseEditor.Validate event and set the ErrorContent event argument. No error is applied if you leave the ErrorContent event argument set to null.

    To forcibly raise the BaseEditor.Validate event, call the BaseEditor.DoValidate method.

  • Specify the error using the BaseEditor.ValidationInfo property.

    The following code sets an error for an editor if the editor's value is null or 0.

    if(textEditor2.EditorValue == null || 
       Convert.ToInt32(textEditor2.EditorValue)==0)
    textEditor2.ValidationInfo = new ValidationInfo("Invalid value");
    
    

    Set the BaseEditor.ValidationInfo property to null to clear the error.

Get the Error Text

Use the BaseEditor.ErrorText property to get the error text.