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 andINotifyDataErrorInfo
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 totrue
(default value). - A user presses the
Enter
key, provided that theBaseEdit.ValidateOnInput
option is set tofalse
.
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 theErrorContent
property set tonull
, 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.
<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.
<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.
<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.
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.
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 theErrorContent
event argument. No error is applied if you leave theErrorContent
event argument set tonull
.To forcibly raise the
BaseEditor.Validate
event, call theBaseEditor.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
or0
.if(textEditor2.EditorValue == null || Convert.ToInt32(textEditor2.EditorValue)==0) textEditor2.ValidationInfo = new ValidationInfo("Invalid value");
Set the
BaseEditor.ValidationInfo
property tonull
to clear the error.
Get the Error Text
Use the BaseEditor.ErrorText
property to get the error text.