Intersoft ClientUI 8 > ClientUI Fundamentals > Data Binding Overview > Data Binding Walkthroughs > Walkthrough: Clear Validation Error on Text Input using ClearErrorOnTextInput |
This walkthrough shows how to display book details information and show an error alert when the book's textbox field is empty, also how to implement ClearErrorOnTextInput which make the error alert directly disappear when user type in the textbox using MVVM pattern.
In this walkthrough, you perform the following tasks:
You need the following components to complete this walkthrough:
The first step is to create a new ClientUI MVVM Application project using Intersoft ClientUI MVVM Application project template in Visual Studio.
Next, you will create the Book model class that represent the data entity used in this walkthrough.
This section shows how to create the Book model class that represents the data entity used in this walkthrough.
C# |
Copy Code
|
---|---|
private string _ID; public string ID { get { return _ID; } set { if (_ID != value) { _ID = value; OnPropertyChanged("ID"); } } } |
C# |
Copy Code
|
---|---|
private string _author; private string _title; private string _category; public string Author { get { return _author; } set { if (_author != value) { _author = value; OnPropertyChanged("Author"); } } } public string Title { get { return _title; } set { if (_title != value) { _title = value; OnPropertyChanged("Title"); } } } public string Category { get { return _category; } set { if (_category != value) { _category = value; OnPropertyChanged("Category"); } } } |
C# |
Copy Code
|
---|---|
private double _price; public double Price { get { return _price; } set { if (_price != value) { _price = value; OnPropertyChanged("Price"); } } } |
C# |
Copy Code
|
---|---|
public bool EnableValidation { get; set; } |
C# |
Copy Code
|
---|---|
public string Author { get { return _author; } set { if (_author != value) { _author = value; ClearError("Author"); OnPropertyChanged("Author"); } } } public string Title { get { return _title; } set { if (_title != value) { _title = value; ClearError("Title"); if (EnableValidation && string.IsNullOrEmpty(this.Title)) SetError("Title", "Title is required"); OnPropertyChanged("Title"); } } } public double Price { get { return _price; } set { if (_price != value) { _price = value; ClearError("Price"); if (EnableValidation && (double.IsNaN(this.Price) || this.Price == 0.0)) SetError("Price", "Price is required"); OnPropertyChanged("Price"); } } } |
C# |
Copy Code
|
---|---|
public Book()
{
} |
This section steps you through the process of creating a page that uses a variety of ClientUI controls such as UXItemsControl, FieldLabel, and StylishLabel.
Property | Value |
---|---|
Height | 110 |
Width | 250 |
HorizontalAlignment | Center |
VerticalAlignment | Center |
Background | White |
CornerRadius | 8 |
Padding | 0,0,0,10 |
XAML |
Copy Code
|
---|---|
<Grid x:Name="LayoutRoot"> <Intersoft:UXItemsControl Height="110" Width="250" HorizontalAlignment="Center" VerticalAlignment="Center" Background="White" CornerRadius="8" Padding="0,0,0,10"> </Intersoft:UXItemsControl> </Grid> |
XAML |
Copy Code
|
---|---|
<Intersoft:UXItemsControl Height="110" Width="250" HorizontalAlignment="Center" VerticalAlignment="Center" Background="White" CornerRadius="8" Padding="0,0,0,10"> <Intersoft:StylishLabel Content="Book Details" CornerRadius="8,8,0,0" Margin="0,0,0,10"/> </Intersoft:UXItemsControl> |
XAML |
Copy Code
|
---|---|
<Intersoft:UXItemsControl Height="110" Width="250" HorizontalAlignment="Center" VerticalAlignment="Center" Background="White" CornerRadius="8" Padding="0,0,0,10"> <Intersoft:StylishLabel Content="Book Details" CornerRadius="8,8,0,0" Margin="0,0,0,10"/> <Intersoft:FieldLabel Header="Title:" HeaderWidth="80" HorizontalHeaderAlignment="Right"> <Intersoft:UXTextBox HorizontalAlignment="Center" Width="132"/> </Intersoft:FieldLabel> </Intersoft:UXItemsControl> |
XAML |
Copy Code
|
---|---|
<Intersoft:FieldLabel Header="Price:" HeaderWidth="80" HorizontalHeaderAlignment="Right"> <Intersoft:UXTextBox HorizontalAlignment="Center" Width="60"/> </Intersoft:FieldLabel> |
XAML |
Copy Code
|
---|---|
... <Grid x:Name="LayoutRoot" Background="Black"> ... |
This section steps you through the process of creating a ViewModel class that contains the properties to describe the View that you created in the previous section. Also in this step, you will create a validation class for the property validation.
C# |
Copy Code
|
---|---|
... namespace ClientUIMVVMApp2.ViewModels { public class ValidationViewModelBase : ViewModelBase, IDataErrorInfo { #region Properties private Dictionary<string, string> _errors = new Dictionary<string, string>(); public virtual bool HasErrors { get { return _errors.Count > 0; } } #endregion #region Public public void SetError(string propertyName, string errorMessage) { _errors[propertyName] = errorMessage; this.OnPropertyChanged(propertyName); } #endregion #region Protected protected void ClearError(string propertyName) { this._errors.Remove(propertyName); } protected void ClearAllErrors() { List<string> properties = new List<string>(); foreach (KeyValuePair<string, string> error in this._errors) properties.Add(error.Key); this._errors.Clear(); foreach (string property in properties) this.OnPropertyChanged(property); } #endregion #region IDataErrorInfo Members public string Error { get { if (this.HasErrors) return this._errors.First().Value; return null; } } public string this[string columnName] { get { if (this._errors.ContainsKey(columnName)) { return this._errors[columnName]; } return string.Empty; } } #endregion } } ... |
C# |
Copy Code
|
---|---|
... public class BookViewModel : ValidationViewModelBase { // Fields private Book _book; // Constructor public BookViewModel() { this.Book = new Book { Title = "Excel 2007 For Dummies", Price = 15.83 }; this.Book.EnableValidation = true; } // Views public Book Book { get { return this._book; } set { if (this._book != value) { this._book = value; OnPropertyChanged("Book"); } } } public string Title { get { return this.Book.Title; } } public string ShortTitle { get { if (this.Book.Title.Length < 80) return this.Title; else return this.Book.Title.Substring(0, 80) + "..."; } } } ... |
In the previous sections, you have learned how to create the Model and ViewModel classes, as well as the View that contains the user interface and controls used in this walkthrough.
This section show how to instantiate the ViewModel in the XAML page and bind the ViewModel that was created in the previous section to the View for example you will bind the Text property of TextBox to Book.Price property of the BookViewModel.
XAML |
Copy Code
|
---|---|
.. <Intersoft:UXPage xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:ViewModels="clr-namespace:ClientUIMVVMApp2.ViewModels" mc:Ignorable="d" .. <Intersoft:UXPage.Resources> <ViewModels:BookViewModel x:Key="BookViewModel"></ViewModels:BookViewModel> </Intersoft:UXPage.Resources> ... |
XAML |
Copy Code
|
---|---|
... <Grid x:Name="LayoutRoot" Background="Black" DataContext="{StaticResource BookViewModel}"> ... |
XAML |
Copy Code
|
---|---|
... <Intersoft:UXItemsControl DataContext="{StaticResource BookViewModel}" Height="110" Width="250" HorizontalAlignment="Center" VerticalAlignment="Center" Background="White" CornerRadius="8" Padding="0,0,0,10"> <Intersoft:StylishLabel Content="Book Details" CornerRadius="8,8,0,0" Margin="0,0,0,10"/> <Intersoft:FieldLabel Header="Title:" HeaderWidth="80" HorizontalHeaderAlignment="Right"> <Intersoft:UXTextBox HorizontalAlignment="Center" Width="132" Text="{Binding Book.Title, Mode=TwoWay}"/> </Intersoft:FieldLabel> <Intersoft:FieldLabel Header="Price:" HeaderWidth="80" HorizontalHeaderAlignment="Right"> <Intersoft:UXTextBox HorizontalAlignment="Center" Width="60" Text="{Binding Book.Price, Mode=TwoWay}"/> </Intersoft:FieldLabel> </Intersoft:UXItemsControl> ... |
XAML |
Copy Code
|
---|---|
... <Intersoft:UXItemsControl DataContext="{StaticResource BookViewModel}" Height="110" Width="250" HorizontalAlignment="Center" VerticalAlignment="Center" Background="White" CornerRadius="8" Padding="0,0,0,10"> <Intersoft:StylishLabel Content="Book Details" CornerRadius="8,8,0,0" Margin="0,0,0,10"/> <Intersoft:FieldLabel Header="Title:" HeaderWidth="80" HorizontalHeaderAlignment="Right"> <Intersoft:UXTextBox HorizontalAlignment="Center" Width="132" Text="{Binding Book.Title, Mode=TwoWay, ValidatesOnDataErrors=True}"/> </Intersoft:FieldLabel> <Intersoft:FieldLabel Header="Price:" HeaderWidth="80" HorizontalHeaderAlignment="Right"> <Intersoft:UXTextBox HorizontalAlignment="Center" Width="60" Text="{Binding Book.Price, Mode=TwoWay, ValidatesOnDataErrors=True, ValidatesOnExceptions=True, StringFormat=\{0:c\}}"/> </Intersoft:FieldLabel> </Intersoft:UXItemsControl> ... |
C# |
Copy Code
|
---|---|
... private void Application_Startup(object sender, StartupEventArgs e) { this.RootVisual = new Views.ShowBookInformation(); } ... |
XAML |
Copy Code
|
---|---|
... <Intersoft:UXItemsControl DataContext="{StaticResource BookViewModel}" Height="110" Width="250" HorizontalAlignment="Center" VerticalAlignment="Center" Background="White" CornerRadius="8" Padding="0,0,0,10"> <Intersoft:StylishLabel Content="Book Details" CornerRadius="8,8,0,0" Margin="0,0,0,10"/> <Intersoft:FieldLabel Header="Title:" HeaderWidth="80" HorizontalHeaderAlignment="Right"> <Intersoft:UXTextBox HorizontalAlignment="Center" Width="132" Text="{Binding Book.Title, Mode=TwoWay, ValidatesOnDataErrors=True}" Intersoft:DataBinding.ClearErrorOnTextInput="True"/> </Intersoft:FieldLabel> <Intersoft:FieldLabel Header="Price:" HeaderWidth="80" HorizontalHeaderAlignment="Right"> <Intersoft:UXTextBox HorizontalAlignment="Center" Width="60" Text="{Binding Book.Price, Mode=TwoWay, ValidatesOnDataErrors=True, ValidatesOnExceptions=True, StringFormat=\{0:c\}}" Intersoft:DataBinding.ClearErrorOnTextInput="True"/> </Intersoft:FieldLabel> </Intersoft:UXItemsControl> ... |
This section lists the complete code used in this walkthrough.
C# |
Copy Code
|
---|---|
using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using ClientUIMVVMApp2.ViewModels; using System.Xml.Linq; namespace ClientUIMVVMApp2.Models { public class Book : ModelBase { #region Constructor public Book() { } #endregion #region Fields private string _ID; private string _author; private string _title; private string _category; private double _price; #endregion #region Properties public bool EnableValidation { get; set; } public string ID { get { return _ID; } set { if (_ID != value) { _ID = value; OnPropertyChanged("ID"); } } } public string Author { get { return _author; } set { if (_author != value) { _author = value; ClearError("Author"); OnPropertyChanged("Author"); } } } public string Title { get { return _title; } set { if (_title != value) { _title = value; ClearError("Title"); if (EnableValidation && string.IsNullOrEmpty(this.Title)) SetError("Title", "Title is required"); OnPropertyChanged("Title"); } } } public string Category { get { return _category; } set { if (_category != value) { _category = value; OnPropertyChanged("Category"); } } } public double Price { get { return _price; } set { if (_price != value) { _price = value; ClearError("Price"); if (EnableValidation && (double.IsNaN(this.Price) || this.Price == 0.0)) SetError("Price", "Price is required"); OnPropertyChanged("Price"); } } } #endregion } } |
XAML |
Copy Code
|
---|---|
<Intersoft:UXPage xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:ViewModels="clr-namespace:ClientUIMVVMApp2.ViewModels" mc:Ignorable="d" xmlns:Intersoft="http://intersoft.clientui.com/schemas" x:Class="ClientUIMVVMApp2.Views.ShowBookInformation" Title="ShowBookInformation Page" d:DesignWidth="640" d:DesignHeight="480"> <Intersoft:UXPage.Resources> <ViewModels:BookViewModel x:Key="BookViewModel"></ViewModels:BookViewModel> </Intersoft:UXPage.Resources> <Grid x:Name="LayoutRoot" Background="Black" > <Intersoft:UXItemsControl DataContext="{StaticResource BookViewModel}" Height="110" Width="250" HorizontalAlignment="Center" VerticalAlignment="Center" Background="White" CornerRadius="8" Padding="0,0,0,10"> <Intersoft:StylishLabel Content="Book Details" CornerRadius="8,8,0,0" Margin="0,0,0,10"/> <Intersoft:FieldLabel Header="Title:" HeaderWidth="80" HorizontalHeaderAlignment="Right"> <Intersoft:UXTextBox HorizontalAlignment="Center" Width="132" Text="{Binding Book.Title, Mode=TwoWay, ValidatesOnDataErrors=True}" Intersoft:DataBinding.ClearErrorOnTextInput="True"/> </Intersoft:FieldLabel> <Intersoft:FieldLabel Header="Price:" HeaderWidth="80" HorizontalHeaderAlignment="Right"> <Intersoft:UXTextBox HorizontalAlignment="Center" Width="60" Text="{Binding Book.Price, Mode=TwoWay, ValidatesOnDataErrors=True, ValidatesOnExceptions=True, StringFormat=\{0:c\}}" Intersoft:DataBinding.ClearErrorOnTextInput="True"/> </Intersoft:FieldLabel> </Intersoft:UXItemsControl> </Grid> </Intersoft:UXPage> |
C# |
Copy Code
|
---|---|
using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using System.ComponentModel; using System.Collections.Generic; using System.Linq; namespace ClientUIMVVMApp2.ViewModels { public class ValidationViewModelBase : ViewModelBase, IDataErrorInfo { #region Properties private Dictionary<string, string> _errors = new Dictionary<string, string>(); public virtual bool HasErrors { get { return _errors.Count > 0; } } #endregion #region Public public void SetError(string propertyName, string errorMessage) { _errors[propertyName] = errorMessage; this.OnPropertyChanged(propertyName); } #endregion #region Protected protected void ClearError(string propertyName) { this._errors.Remove(propertyName); } protected void ClearAllErrors() { List<string> properties = new List<string>(); foreach (KeyValuePair<string, string> error in this._errors) properties.Add(error.Key); this._errors.Clear(); foreach (string property in properties) this.OnPropertyChanged(property); } #endregion #region IDataErrorInfo Members public string Error { get { if (this.HasErrors) return this._errors.First().Value; return null; } } public string this[string columnName] { get { if (this._errors.ContainsKey(columnName)) { return this._errors[columnName]; } return string.Empty; } } #endregion } } |
C# |
Copy Code
|
---|---|
using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using ClientUIMVVMApp2.Models; using System.Windows.Resources; using System.Xml.Linq; using System.Linq; using System.Collections.ObjectModel; namespace ClientUIMVVMApp2.ViewModels { public class BookViewModel : ValidationViewModelBase { // Fields private Book _book; // Constructor public BookViewModel() { this.Book = new Book { Title = "Excel 2007 For Dummies", Price = 15.83 }; this.Book.EnableValidation = true; } // Views public Book Book { get { return this._book; } set { if (this._book != value) { this._book = value; OnPropertyChanged("Book"); } } } public string Title { get { return this.Book.Title; } } public string ShortTitle { get { if (this.Book.Title.Length < 80) return this.Title; else return this.Book.Title.Substring(0, 80) + "..."; } } } } |