windowsforms-751-controls-and-libraries-data-grid-data-editing-and-validation-errorinfo-support-error-notification-support-for-data-sources.md
If your data source is a DataView or DataTable, you can indicate invalid values in any row at the data source level, using the DataRow.SetColumnError method. The grid control will display error icons ( ) within cells that contain these errors. When you hover with the mouse cursor over the error icons, the grid shows tooltips containing error text.
To support error notifications for custom data sources, implement the IDataErrorInfo or IDXDataErrorInfo interface for your business object (the class that encapsulates records).
Tip
The grid control has methods to set errors for the focused row and its individual cells. These methods are supported for all data source types, even if they do not implement the IDataErrorInfo or IDXDataErrorInfo interface. For more information, refer to the Internal ErrorInfo Support document.
The following example implements the IDataErrorInfo interface to support error notifications for a business object (Customer). Errors are raised if the Customer.FirstName or Customer.LastName fields are empty.
The GridControl automatically displays error icons for cells with invalid values. To display error icons in standalone editors, assign the DXErrorProvider to a data source.
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.DXErrorProvider;
using DevExpress.XtraGrid;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Forms;
namespace DXApplication19 {
public partial class Form1 : DevExpress.XtraEditors.XtraForm {
public Form1() {
InitializeComponent();
GridControl gridControl1 = new GridControl();
Controls.Add(gridControl1);
gridControl1.Dock = DockStyle.Fill;
//Create a data source
BindingList<Customer> list = new BindingList<Customer>();
list.Add(new Customer("Andrew", "Weber"));
list.Add(new Customer("", "Kovar")); // An invalid first name
list.Add(new Customer("Kathy", "")); // An invalid last name
BindingSource bindingSource1 = new BindingSource(list, "");
gridControl1.DataSource = bindingSource1;
// To show data source errors in standalone editors, bind a DXErrorProvider to the data source.
DXErrorProvider dxErrorProvider1 = new DXErrorProvider(this);
dxErrorProvider1.DataSource = bindingSource1;
// Create a TextEdit control and bind it to the First Name field
TextEdit textEdit1 = new TextEdit();
textEdit1.DataBindings.Add(new Binding("EditValue", bindingSource1, "FirstName"));
LabelControl label = new LabelControl();
label.Padding = new Padding(0, 30, 0, 5);
label.Text = "TextEdit bound to FirstName field:";
Controls.Add(label);
label.Dock = DockStyle.Bottom;
Controls.Add(textEdit1);
textEdit1.Dock = DockStyle.Bottom;
}
}
public class Customer: IDataErrorInfo, INotifyPropertyChanged {
public Customer(string firstName, string lastName) {
FirstName = firstName;
LastName = lastName;
}
string firstName;
public string FirstName {
get {
return firstName;
}
set {
ValidateValue(value);
firstName = value;
OnPropertyChanged();
}
}
string lastName;
public string LastName {
get {
return lastName;
}
set {
ValidateValue(value);
lastName = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
public virtual void OnPropertyChanged([CallerMemberName] String propertyName = "") {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
// Stores errors for all properties of the Customer class.
Dictionary<string, string> PropertyErrors = new Dictionary<string, string>();
string IDataErrorInfo.this[string propertyName] {
get {
string errorText;
return PropertyErrors.TryGetValue(propertyName, out errorText) ? errorText : null;
}
}
string IDataErrorInfo.Error => string.Empty;
// Clears or sets errors for the FirstName and LastName fields.
void ValidateValue(string value, [CallerMemberName] String propertyName="") {
bool isValid = !string.IsNullOrEmpty(value);
if (isValid) {
//Clear a previous error, if any.
PropertyErrors.Remove(propertyName);
}
else {
//Set an error.
string errorText = propertyName + " is required";
PropertyErrors[propertyName] = errorText;
}
}
}
}
Imports System.ComponentModel
Imports System.Runtime.CompilerServices
Imports DevExpress.XtraEditors
Imports DevExpress.XtraEditors.DXErrorProvider
Imports DevExpress.XtraGrid
Partial Public Class Form1
Public Sub New()
InitializeComponent()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim gridControl1 As GridControl = New GridControl()
Controls.Add(gridControl1)
gridControl1.Dock = DockStyle.Fill
'Create a data source
Dim list As BindingList(Of Customer) = New BindingList(Of Customer)()
list.Add(New Customer("Andrew", "Weber"))
list.Add(New Customer("", "Kovar")) ' An invalid first name
list.Add(New Customer("Kathy", "")) ' An invalid last name
Dim bindingSource1 As BindingSource = New BindingSource(list, "")
gridControl1.DataSource = bindingSource1
' To show data source errors in standalone editors, bind a DXErrorProvider to the data source.
Dim dxErrorProvider1 As New DXErrorProvider(Me)
dxErrorProvider1.DataSource = bindingSource1
' Create a TextEdit control and bind it to the First Name field
Dim textEdit1 As TextEdit = New TextEdit()
textEdit1.DataBindings.Add(New Binding("EditValue", bindingSource1, "FirstName"))
Dim label As LabelControl = New LabelControl()
label.Padding = New Padding(0, 30, 0, 5)
label.Text = "TextEdit bound to FirstName field:"
Controls.Add(label)
label.Dock = DockStyle.Bottom
Controls.Add(textEdit1)
textEdit1.Dock = DockStyle.Bottom
End Sub
End Class
Public Class Customer
Implements IDataErrorInfo, INotifyPropertyChanged
Public Sub New(ByVal firstName_Renamed As String, ByVal lastName_Renamed As String)
Me.FirstName = firstName_Renamed
Me.LastName = lastName_Renamed
End Sub
Private firstName_Renamed As String
Public Property FirstName() As String
Get
Return firstName_Renamed
End Get
Set
ValidateValue(Value)
firstName_Renamed = Value
OnPropertyChanged()
End Set
End Property
Private lastName_Renamed As String
Public Property LastName() As String
Get
Return lastName_Renamed
End Get
Set
ValidateValue(Value)
lastName_Renamed = Value
OnPropertyChanged()
End Set
End Property
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Public Overridable Sub OnPropertyChanged(<CallerMemberName()> Optional ByVal propertyName As String = Nothing)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
' Stores errors for all properties of the Customer class.
Private PropertyErrors As Dictionary(Of String, String) = New Dictionary(Of String, String)()
Private ReadOnly Property Item(ByVal propertyName As String) As String Implements IDataErrorInfo.Item
Get
Dim errorText As String = ""
If PropertyErrors.TryGetValue(propertyName, errorText) Then
Return errorText
Else
Return Nothing
End If
End Get
End Property
Private ReadOnly Property [Error] As String Implements IDataErrorInfo.Error
Get
Return ""
End Get
End Property
Private Sub ValidateValue(ByVal value As String, <CallerMemberName> ByVal Optional propertyName As String = Nothing)
Dim isValid As Boolean = Not String.IsNullOrEmpty(value)
If isValid Then
'Clear a previous error, if any.
PropertyErrors.Remove(propertyName)
Else
'Set an error.
Dim errorText As String = propertyName & " is required"
PropertyErrors(propertyName) = errorText
End If
End Sub
End Class
See Also
Edit Data. Create Cell Editors. Validate User Input