Windows-XAML/Template10.Validation

Name: Template10.Validation

Owner: Windows XAML

Description: null

Created: 2016-09-07 22:14:16.0

Updated: 2018-04-06 00:36:36.0

Pushed: 2017-07-28 21:41:18.0

Homepage: null

Size: 1144

Language: C#

GitHub Committers

UserMost Recent Commit# Commits

Other Committers

UserEmailMost Recent Commit# Commits

README

Validation in Universal Windows Platform

In Windows UWP XAML/C# apps, developers will discover that input controls do not support DataAnnotation or ExceptionValidationRule or IDataErrorInfo or INotifyDataErrorInfo or BindingValidationError. Even if the platform included these capabilities, there are significant limitations to each that make them a limiting option for application with significant real-world data validation requirements.

nuget

Introducing Template10 Validation

These validation libraries provide UWP developers a comprehensive solution to data validation that solves problems in a realistic and usable way. The associated sample application demonstrates the use and syntax. If you have feedback or a bug to report, do it here: https://github.com/Windows-XAML/Template10/issues.

Get started

To get started with validation, your models need to inherit Template10.Validation.ValidatableModelBase. This will include an implementation of INotifyPropertyChanged in case you need it in your logic. Should your poco classes (models) not support inheriting from a new base class, then this validation library will not work for you. The enhancements to your model(s) will include:

ValidatableModelBase properties
ValidatableModelBase methods

In addition to inheriting from ValidatableModelBase, both the setter and getters of your model properties will need to change to the following syntax in order to take part in the underlying change tracking mechanism.

Your model before
ic class User 

public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public override string ToString() => $"{FirstName} {LastName}";

Your model after
ic class User : Template10.Validation.ValidatableModelBase

public int Id { get; set; }
public string FirstName { get { return Read<string>(); } set { Write(value); } }
public string LastName { get { return Read<string>(); } set { Write(value); } }
public override string ToString() => $"{FirstName} {LastName}";

Adding validation logic

Once you have implemented these changes, you need to set the Validator property of your model - typically when they are created or just before they are exposed in your view-model. (Note: It is not required that you use the MVVP design pattern to use this library - but if you don't you're probably building your app all wrong). You would set your validator something like this:

user = new User

FirstName = "Jerry",
LastName = "Nixon",
Validator = i =>
{
    var u = i as User;
    if (string.IsNullOrEmpty(u.FirstName))
    {
        u.Properties[nameof(u.FirstName)].Errors.Add("First name is required");
    }
    if (string.IsNullOrEmpty(u.LastName))
    {
        u.Properties[nameof(u.LastName)].Errors.Add("Last name is required");
    }
},

Notice in the code above how you are adding one or more errors to the Errors property of the model's property; you are not adding to the Errors property of the model. This allows errors on a field level. Property errors are automatically propagated to the model-level property Errors. Any changes to that list will be overwritten.

Calling validation logic

Once the validation logic is injected into the model, you can call the model's Validate() method to assess the current state of the model. You can repeatedly call Validate() as the workflow in your app requires. If the validation logic has significant cost, calling Validate() too frequently could have a performance cost to your app.

New properties of your properties

Above you saw how each property has an Errors property. In addition, there is a Value property and these others:

Properties
Event(s)
Methods
Error indicator

You will see that most of these properties are managed automatically by the base class. Calling MarkAsClean() or Revert() impacts IsDirty and Value respectively. That being said, you can also use them in tandem with the control wrapper that ships in the library. You would use it like this:

idate:ControlWrapper PropertyName="FirstName">
<TextBox Width="{StaticResource FieldWidth}"
    Header="First Name"
    Text="{Binding FirstName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
lidate:ControlWrapper>

By default the visual looks like this:

default look

Customized error indicator

The visual definition of the wrapper is defined in the library (https://github.com/Windows-XAML/Template10.Validation/blob/master/Library/Themes/Generic.xaml) and you can override it simply by changing the Template property of the wrapper. Here's how you might do it:

idate:ControlWrapper PropertyName="FirstName">
<validate:ControlWrapper.Template>
    <ControlTemplate TargetType="validate:ControlWrapper">
        <StackPanel DataContext="{TemplateBinding Property}">
            <TextBlock Text="IsValid" />
            <TextBlock Text="{Binding IsValid}" />
            <TextBlock Text="Errors" />
            <TextBlock Text="{Binding Errors.Count}" />
            <ContentPresenter Content="{TemplateBinding Content}" />
        </StackPanel>
    </ControlTemplate>
</validate:ControlWrapper.Template>
<TextBox Width="{StaticResource FieldWidth}"
            Header="First Name"
            Text="{Binding FirstName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
lidate:ControlWrapper>

In the XAML above the ControlTemplate is created in-line, but could easily be moved to a resource and re-used in multiple controls. It also demonstrates how every control could have a separate look, if desired. The XAML above would render a look something like this:

custom look

I realize that's a silly use of the control, but it demonstrates an easy starting place.

I hope you enjoy Template 10 Validation!


This work is supported by the National Institutes of Health's National Center for Advancing Translational Sciences, Grant Number U24TR002306. This work is solely the responsibility of the creators and does not necessarily represent the official views of the National Institutes of Health.