New to Telerik UI for Xamarin? Download free 30-day trial

Validation Command

The RadDataGrid control provides a validation command that has an entry point for validating cells content. The execution parameter is of type ValidateCellContext that exposes the following properties:

  • CellInfo: Gets the cell info associated with the operation.
  • Errors: Gets or sets the errors (if any) that occurred during the validation.

Example

Here is an example how the RadDataGrid ValidateCell Command works:

First, create class Data (our business object) that inherits from the INotifyDataErrorInfo and INotifyPropertyChanged interfaces.

We are going to do the validation through the INotifyDataErrorInfo interface.

public class Data : INotifyDataErrorInfo, INotifyPropertyChanged
{
    private Dictionary<string, HashSet<object>> errors = new Dictionary<string, HashSet<object>>();
    private string country;

    public string Country
    {
        get
        {
            return this.country;
        }

        set
        {
            this.country = value;

            if (this.country.Length > 15)
            {
                this.AddError("Country", string.Format("Country too long", new DateTime()));
            }
            else
            {
                this.RemoveErrors("Country");
            }

            this.OnPropertyChanged("Country");
        }
    }

    public string Capital { get; set; }

    public bool HasErrors
    {
        get
        {
            return this.errors.Count > 0;
        }
    }

    public IEnumerable GetErrors(string propertyName)
    {
        if (string.IsNullOrEmpty(propertyName))
        {
            return this.errors.SelectMany(c => c.Value);
        }

        HashSet<object> propertyErrors;

        this.errors.TryGetValue(propertyName, out propertyErrors);

        return propertyErrors ?? Enumerable.Empty<object>();
    }

    protected virtual void AddError(string propertyName, object errorMessage)
    {
        HashSet<object> propertyErrors;

        if (!this.errors.TryGetValue(propertyName, out propertyErrors))
        {
            propertyErrors = new HashSet<object>();
            this.errors.Add(propertyName, propertyErrors);

            propertyErrors.Add(errorMessage);

            this.OnErrorsChanged(propertyName);
        }
        else
        {
            if (!propertyErrors.Contains(errorMessage))
            {
                propertyErrors.Add(errorMessage);
                this.OnErrorsChanged(propertyName);
            }
        }
    }

    protected virtual void RemoveErrors(string propertyName = null)
    {
        if (string.IsNullOrEmpty(propertyName))
        {
            if (this.errors.Count > 0)
            {
                this.errors.Clear();
                this.OnErrorsChanged(propertyName);
            }
        }
        else
        {
            if (this.errors.Remove(propertyName))
            {
                this.OnErrorsChanged(propertyName);
            }
        }
    }

    public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;

    protected virtual void OnErrorsChanged(string propertyName)
    {
        if (this.ErrorsChanged != null)
        {
            this.ErrorsChanged(this, new DataErrorsChangedEventArgs(propertyName));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
}

Then create a ViewModel with a collection of Data objects:

public class ViewModel : INotifyPropertyChanged
{
    public ObservableCollection<Data> Items { get; set; }
    public ViewModel()
    {
        this.Items = new ObservableCollection<Data>()
        {
             new Data { Country = "India", Capital = "New Delhi"},
             new Data { Country = "South Africa", Capital = "Cape Town"},
             new Data { Country = "Nigeria", Capital = "Abuja" },
             new Data { Country = "Singapore", Capital = "Singapore" }
       };
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
}

Then handle the CellTap action as a Command. First, create a class that inherits from the DataGridCommand and set its Id property accordingly. You would also need to override CanExecute and Execute methods as demostrated in the example below:

public class ValidateCellCommand : DataGridCommand
{
    Grid grid;
    public ValidateCellCommand(Grid grid)
    {
        this.Id = DataGridCommandId.ValidateCell;
        this.grid = grid;
    }

    public override void Execute(object parameter)
    {
        var context = (ValidateCellContext)parameter;
        this.grid.IsVisible = context.Errors.Count > 0;
    }
}

Then set the BindingContext to be the ViewModel and add this Command to the Commands collection of the RadDataGrid instance:

this.BindingContext = new ViewModel();
this.dataGrid.Commands.Add(new ValidateCellCommand(errorContainer));

Define the RadDataGrid in XAML:

<Grid Margin="0,20,0,0">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <Grid x:Name="errorContainer" 
          IsVisible="false">
        <BoxView BackgroundColor="DarkRed" />
        <Label Text="country name length must be less than 15 symbols" 
               FontSize="15"
               HorizontalOptions="CenterAndExpand"
               VerticalOptions="CenterAndExpand"
               HorizontalTextAlignment="Center"
               TextColor="White"/>
    </Grid>

    <telerikDataGrid:RadDataGrid x:Name="dataGrid"
                                 Grid.Row="1"
                                 UserEditMode="Cell"
                                 AutoGenerateColumns="True"
                                 ItemsSource="{Binding Items}">
    </telerikDataGrid:RadDataGrid>
</Grid>

SDK Samples Browser application contains an example that shows how to use the ValidateCell Command. The Validation example is located in the DataGrid/Commands folder.

See Also

In this article