First of all, create Windows 8 Blank App project and name is whatever you want. Then
get Prism for Windows 8 store apps, you can do it via Manage NuGet packages from
Visual Studio and search for “Prism store apps” or run following command from
package manager console:
PM> Install-package Prism.StoreApps
Now we will quickly setup simple screen following MVVM. For that, just add class
named Person with following set of properties as shown in Listing 1.0.
public class Person : ValidatableBindableBase
{
private string firstName;
[Required(ErrorMessage = "First name is required.")]
public string FirstName
{
get { return firstName; }
set
{
firstName = value;
this.OnPropertyChanged("FirstName");
}
}
private string lastName;
public string LastName
{
get { return lastName; }
set
{
lastName = value;
this.OnPropertyChanged("LastName");
}
}
private string email;
[Required(ErrorMessage = "Email is required.")]
[RegularExpression(@"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$", ErrorMessage = "Email is invalid.")]
public string Email
{
get { return email; }
set
{
email = value;
this.OnPropertyChanged("Email");
}
}
}
Listing 1.0 Person class inheriting ValidatableBindableBase
As per Listing 1.0, in the Person class, we have used DataAnnotations to apply validation
for FirstName and Email property and made them required as well Email property
to follow proper email format by validating through regex. Other thing to notice
is that we have inherited the class from ValidatableBindableBase. This base class
has method named ValidateProperties which enables validating all these properties.
Apart from that, it has few useful events and properties which helps validating
the object as shown in Listing 1.1 below.
public class ValidatableBindableBase : BindableBase, IValidatableBindableBase, INotifyPropertyChanged
{
public ValidatableBindableBase();
public BindableValidator Errors { get; }
public bool IsValidationEnabled { get; set; }
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
public ReadOnlyDictionary<string, ReadOnlyCollection<string>> GetAllErrors();
public void SetAllErrors(IDictionary<string, ReadOnlyCollection<string>> entityErrors);
protected override bool SetProperty<T>(ref T storage, T value, string propertyName =
null);
public bool ValidateProperties();
}
Listing 1.1 ValidatableBindableBase class
Now it’s time to create ViewModel class which simply will have a Person property
to bind to the View as well Validate person command to validate all these properties
as shown in Listing 1.2 below.
using Microsoft.Practices.Prism.StoreApps;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Input;
namespace PrismValidation
{
public class MainViewModel : BindableBase
{
public Person Person { get; set; }
public ICommand ValidatePersonCommand { get; set; }
private ObservableCollection<string> allErrors;
public ObservableCollection<string> AllErrors
{
get { return allErrors; }
set
{
allErrors = value;
this.OnPropertyChanged("AllErrors");
}
}
public MainViewModel()
{
this.Person = new Person();
this.ValidatePersonCommand = new DelegateCommand(this.ExecuteValidatePerson);
}
private void ExecuteValidatePerson()
{
if (!this.Person.ValidateProperties())
{
this.AllErrors = new ObservableCollection<string>(this.Person.Errors.GetAllErrors().Values.SelectMany(c => c).ToList());
}
else
{
this.AllErrors = new ObservableCollection<string> { "Person is valid." };
}
}
}
}
Listing 1.2 MainViewModel class
Listing 1.2 shows that MainViewModel class has one Person property to bind to the
view as well ValidatePersonCommand which we will bind to Button control in the
view to enable validation. The AllErrors collection will display all the errors
on the UI. Let’s complete remaining View part of this example to see it in action.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" >
<StackPanel.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="22"/>
<Setter Property="Margin" Value="10"/>
<Setter Property="FontSize" Value="22"/>
</Style>
<Style TargetType="TextBox">
<Setter Property="FontSize" Value="22"/>
<Setter Property="Margin" Value="10"/>
<Setter Property="FontSize" Value="22"/>
<Setter Property="Width" Value="500"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
</Style>
</StackPanel.Resources>
<TextBlock>First Name</TextBlock>
<TextBox Text="{Binding Person.FirstName, Mode=TwoWay}"/>
<TextBlock>Last Name</TextBlock>
<TextBox Text="{Binding Person.LastName, Mode=TwoWay}"/>
<TextBlock>Email</TextBlock>
<TextBox Text="{Binding Person.Email, Mode=TwoWay}"/>
<Button Command="{Binding ValidatePersonCommand}" Margin="10" FontSize="28">Validate</Button>
<ItemsControl ItemsSource="{Binding AllErrors}" Margin="10" FontSize="22" Foreground="Yellow"/>
</StackPanel>
</Grid>
Listing 1.3 MainPage.xaml markup
The markup is self-explanatory as it binds controls to the Person property of the
MainViewModel as well ValidatePersonCommand along with AllErrors collection to
show errors in the view. Now last remaining thing is to set DataContext of the
MainPage to the instance of MainViewModel as following in MainPage’s constructor.
public MainPage()
{
this.InitializeComponent();
this.DataContext = new MainViewModel();
}
Listing 1.4 Setting DataContext for MainPage
We are good to press F5 and see it in action.
• Just Press Validate button and you will see it reports two errors.
• Enter some invalid format for Email and hit validate to see error being report.
You can grab the source here.