GridViewBase.ValidateRow Event

Occurs when you make changes within a row and move focus to another row.

Namespace: DevExpress.Xpf.Grid

Assembly: DevExpress.Xpf.Grid.v21.1.dll


public event GridRowValidationEventHandler ValidateRow

Event Data

The ValidateRow event's data class is GridRowValidationEventArgs. The following properties provide information specific to this event:

Property Description
CancellationToken Gets an object that notifies that the Update operation should be canceled.
Culture Gets the culture related to the validation. Inherited from ValidationEventArgs.
ErrorContent Gets or sets an object that describes the validation error. Inherited from ValidationEventArgs.
ErrorType Gets or sets the error icon type. Inherited from ValidationEventArgs.
Handled Gets or sets a value that indicates the present state of the event handling for a routed event as it travels the route. Inherited from RoutedEventArgs.
IsValid Gets or sets a value specifying whether the value is valid. Inherited from ValidationEventArgs.
OriginalSource Gets the original reporting source as determined by pure hit testing, before any possible Source adjustment by a parent class. Inherited from RoutedEventArgs.
RoutedEvent Gets or sets the RoutedEvent associated with this RoutedEventArgs instance. Inherited from RoutedEventArgs.
Row Gets the processed row.
RowHandle Gets the processed row’s handle.
Source Gets or sets a reference to the object that raised the event. Inherited from RoutedEventArgs.
UpdateRowResult Gets or sets a task that allows you to asynchronously post changes to an underlying data source (database).
UpdateSource Gets the action that caused the validation. Inherited from ValidationEventArgs.
UseCancellationToken Gets or sets whether the Update operation can be canceled.
Value Gets the editor’s value. Inherited from ValidationEventArgs.

The event data class exposes the following methods:

Method Description
InvokeEventHandler(Delegate, Object) When overridden in a derived class, provides a way to invoke event handlers in a type-specific way, which can increase efficiency over the base implementation. Inherited from RoutedEventArgs.
OnSetSource(Object) When overridden in a derived class, provides a notification callback entry point whenever the value of the Source property of an instance changes. Inherited from RoutedEventArgs.
SetError(Object) Marks the processed input value as invalid and displays an error within the editor. Inherited from ValidationEventArgs.
SetError(Object, ErrorType) Marks the processed input value as invalid and displays an error within the editor with the specified error icon type. Inherited from ValidationEventArgs.


Handle this event to validate changes made within the focused row. You can also invoke the DataViewBase.CommitEditing method to validate changes.

The Row and RowHandle properties return the processed row and the row’s handle, respectively.

You can obtain cell values and verify if they meet your validation criteria. If these values are incorrect, set the IsValid property to false.

Refer to the following topic for more information: Row Validation.

If you want to maintain a clean MVVM pattern and process the row validate operation in a View Model, create a command and bind it to the ValidateRowCommand property.

Use the UpdateRowResult property to validate row data asynchronously.


This example shows how to check if a user enters valid data into a row. Handle the GridViewBase.ValidateRow and GridViewBase.InvalidRowException events to validate the focused row’s data. If the data is invalid, do not allow the user to move focus to another row until the invalid values are corrected.

The Task class implements the IDXDataErrorInfo interface and allows you to get error descriptions for the entire row and for individual cells (data source fields). Error icons appear in cells that contain invalid values. Hover the mouse pointer over an error icon to display a tooltip with an error description.

View Example

<Window x:Class="DXGrid_ValidateRow.Window1" 
    Title="Window1" Height="300" Width="500">
        <dxg:GridControl x:Name="grid">
                <dxg:GridColumn FieldName="TaskName" />
                <dxg:GridColumn FieldName="StartDate" />
                <dxg:GridColumn FieldName="EndDate" />
                <dxg:TableView AutoWidth="True" 
                               InvalidRowException="TableView_InvalidRowException" />
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Data;
using DevExpress.Xpf.Grid;
using DevExpress.XtraEditors.DXErrorProvider;

namespace DXGrid_ValidateRow {
    public partial class Window1 : Window {
        public Window1() {
            grid.ItemsSource = TaskList.GetData();

        private void TableView_ValidateRow(object sender, GridRowValidationEventArgs e) {
            DateTime startDate = ((Task)e.Row).StartDate;
            DateTime endDate = ((Task)e.Row).EndDate;
            e.IsValid = startDate < endDate;

        private void TableView_InvalidRowException(object sender, InvalidRowExceptionEventArgs e) {
            e.ExceptionMode = ExceptionMode.NoAction;

    public class TaskList {
        public static List<Task> GetData() {
            List<Task> data = new List<Task>();
            data.Add(new Task() { TaskName = "Complete Project A",
                StartDate = new DateTime(2009, 7, 17), EndDate = new DateTime(2009, 7, 10) });
            data.Add(new Task() { TaskName = "Test Website",
                StartDate = new DateTime(2009, 7, 10), EndDate = new DateTime(2009, 7, 12) });
            data.Add(new Task() { TaskName = "Publish Docs",
                StartDate = new DateTime(2009, 7, 4), EndDate = new DateTime(2009, 7, 6) });
            return data;

    public class Task : IDXDataErrorInfo {
        public string TaskName { get; set; }
        public DateTime StartDate { get; set; }
        public DateTime EndDate { get; set; }
        void IDXDataErrorInfo.GetError(ErrorInfo info) {
            if (StartDate > EndDate) {
                    "Either StartDate or EndDate should be corrected.",
        void IDXDataErrorInfo.GetPropertyError(string propertyName, ErrorInfo info) {
            switch (propertyName) {
                case "StartDate":
                    if (StartDate > EndDate)
                            "StartDate must be less than EndDate",
                case "EndDate":
                    if (StartDate > EndDate)
                            "EndDate must be greater than StartDate",
                case "TaskName":
                    if (IsStringEmpty(TaskName))
                            "Task name hasn't been entered",
        void SetErrorInfo(ErrorInfo info, string errorText, ErrorType errorType) {
            info.ErrorText = errorText;
            info.ErrorType = errorType;
        bool IsStringEmpty(string str) {
            return (str != null && str.Trim().Length == 0);
See Also