Validate User Input in Data Form for .NET MAUI
- 5 minutes to read
Data editors in a DataFormView allow users to input different types of information: phone numbers, zip codes, email addresses, and so on. You can validate the user input before it is committed to the underlying data object.
Ways to Validate Data
The Data Form allows you to validate data in the following ways: you can annotate data fields with attributes, handle validation events, or your data object can implement an interface that notifies you about errors.
Data Annotations
The Data Form supports ValidationAttribute descendants. For example, you can apply the EmailAddress attribute to a data field to ensure that a user entered a valid email address. The code below shows how to check if a user entered a valid email address, check if a password meets a security policy, and make both of these fields required.
using System.ComponentModel.DataAnnotations;
// ...
namespace DataFormExample {
public class PersonalInfo {
[EmailAddress(ErrorMessage = "Not valid email address")]
[Required(ErrorMessage = "Required")]
public string Email { get; set; }
[StringLength(64, MinimumLength = 8,
ErrorMessage = "The password should contain at least 8 characters.")]
[Required(ErrorMessage = "Required")]
public string Password { get; set; }
// ...
}
}
Validation Events
If data annotations do not meet your needs, you can handle the following events to validate user input according to your logic:
- ValidateProperty
- Allows you to validate a specific field on the form. The DataFormView raises the
ValidateProperty
event depending on the ValidationMode property value - the event can be raised when a user inputs data, when the editor loses focus, or when the Validate or Commit method is called explicitly.
Use the PropertyName event argument to determine the processed data field. The CurrentValue and NewValue arguments specify the current data field value and the value that should be validated. TheDataFormView
raises theValidateProperty
event only if theCurrentValue
andNewValue
are different. If the new value is not valid, set the HasError argument totrue
and use the ErrorText argument to notify the user about the error. - ValidateForm
- Allows you to validate all data fields on the form. The DataFormView raises the
ValidateForm
event when you call the Validate or Commit methods.
TheValidateForm
event stores new values and error messages in the NewValues and Errors dictionaries (keys are data field names). Use the HasErrors argument to specify whether the form is valid. The DataObject argument allows you to obtain the underlying data object.
The code below shows how to ensure that a password contains at least 8 characters and includes uppercase and lowercase characters, numbers, and special characters.
using DevExpress.Maui.DataForm;
// ...
public partial class MainPage : ContentPage {
public MainPage() {
InitializeComponent();
dataForm.DataObject = new PersonalInfo();
dataForm.ValidateProperty += dataForm_ValidateProperty;
}
private void dataForm_ValidateProperty(object sender, DataFormPropertyValidationEventArgs e) {
if (e.PropertyName == "Password") {
var regex = new Regex(@"^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#\$%\^&\*])(?=.{8,})");
if (!regex.IsMatch(e.NewValue.ToString())) {
e.HasError = true;
e.ErrorText = "The password must contain at least 8 characters " +
"including uppercase, lowercase, numbers, and special characters.";
}
}
}
}
The example below requires a phone number or email address.
using DevExpress.Maui.DataForm;
// ...
public partial class MainPage : ContentPage {
public MainPage() {
InitializeComponent();
dataForm.DataObject = new PersonalInfo();
dataForm.ValidateForm += dataForm_ValidateForm;
}
private void dataForm_ValidateForm(object sender, DataFormValidationEventArgs e) {
if(e.NewValues["Email"] == null && e.NewValues["PhoneNumber"] == null) {
e.HasErrors = true;
e.Errors["Email"] = e.Errors["PhoneNumber"] = "Email address or phone number is required.";
}
}
}
The DataFormView runs validation mechanisms when it posts an editor’s value to the underlying data item properties. The CommitMode property controls this behavior. If you enable immediate posting in this property (CommitMode
= Input
), the validation also occurs immediately. This means that the CommitMode
definition has a higher priority than ValidationMode
.
For example, if you set CommitMode
to Manually
, the underlying data item properties are not posted to the underlying data item object until you call the Commit
method. However, the validation can be executed either on user input (ValidationMode
= Input
) or when a user navigates to a different editor in the form (ValidationMode
= LostFocus
).
Error Notification Interfaces
You can implement the INotifyDataErrorInfo or IDataErrorInfo interface in the underlying data object to notify users about errors. Use this approach to validate a value after it is committed to the data object. The code below shows how to validate passwords.
using System.ComponentModel;
// ...
namespace DataFormExample {
public class PersonalInfo : IDataErrorInfo {
string IDataErrorInfo.this[string columnName] {
get {
if (columnName == "Password" && this.Password.Length < 8) {
return "The password should contain at least 8 characters.";
}
return null;
}
}
//...
string IDataErrorInfo.Error => throw new NotImplementedException();
}
}
When Data is Validated
The ValidationMode property specifies when the data form validates the user input. The following modes are supported:
- LostFocus—the form validates a data field when an editor loses focus.
- Input—the form validates a data field when its value changes.
- Manually (the default value)—the form validates data fields when the Validate() method is called. You can also call the Validate(String) method to validate a specific data field.
<dxdf:DataFormView x:Name="dataForm"
ValidationMode="LostFocus">
<!-- ... -->
</dxdf:DataFormView>
Note
The form also validates data fields when the Commit() method is called. If values are not valid, they are not committed to the underlying object.