ValidatableBase for Universal WinRT apps on GitHub

I spent yesterday building a better way to do validations while writing a Universal WinRT app, and blogged about my end product. I decided I'd go ahead and make a GitHub project and upload the source, so it is freely available to anyone who needs Validation until prism and Universal WinRT apps can support it out of the box.

The following is from the projects ReadMe.md

ValidatableBase

Model Validation for Universal WinRT Apps. Since Universal WinRT apps targeting Windows 8.1 and Windows Phone 8.1 lack built in, easy to use data Validation, I wrote a quick model object that can be used to add validation to your apps.

An example model, providing validation making sure the name is not blank.

public class ModelFixture : ValidatableBase
{
    private string name;

    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    public override void Validate()
    {
        this.ValidateProperty((failureMessage) =>
            {
                if (string.IsNullOrEmpty(this.Name))
                {
                    return new ValidationErrorMessage(failureMessage);
                }
                return null;
            },
            failureMessage: "Name can not be blank!",
            propertyName: "Name");

        base.Validate();
    }
}

Advanced Example validating multiple business rules on a property, for multiple properties.

public class User : ValidatableBase
{
    /// < summary>
    /// The Email backing field.
    /// < /summary>
    private string email = string.Empty;

    /// < summary>
    /// The Password backing field.
    /// < /summary>
    private string password = string.Empty;

    /// < summary>
    /// Gets the Email.
    /// < /summary>
    /// < value>
    /// The Email.
    /// < /value>
    public string Email
    {
        get 
        {
            return this.email;
        }

        set 
        { 
            this.email = value;
            this.OnPropertyChanged("Email");
        }
    }
    /// < summary>
    /// Gets the Password.
    /// < /summary>
    /// < value>
    /// The Password.
    /// < /value>
    public string Password
    {
        get 
        { 
            return this.password; 
        }

        set 
        { 
            this.password = value;
            this.OnPropertyChanged("Password");
        }
    }

    /// < summary>
    /// Performs validation on the User.
    /// < /summary>
    public override void Validate()
    {
        this.ValidateProperty(this.ValidateEmailIsNotEmpty, "Invalid Email Address.", "Email");
        this.ValidateProperty(this.ValidateEmailIsFormatted, "Email Address is not in the correct format.", "Email");
        this.ValidateProperty(this.ValidatePasswordIsNotEmpty, "Password can not be empty.", "Password");
        this.ValidateProperty(this.ValidatePasswordIsToShort, "Password must be greater than 8 characters.", "Password");
        this.ValidateProperty(this.ValidateIfPasswordContainsSpaces, "Password must not contain spaces.", "Password");

        base.Validate();
    }

    /// < summary>
    /// Validates that the email is not empty.
    /// < /summary>
    /// < param name="failureMessage">The message to supply the error collection if validation fails.</param>
    /// < returns>Returns a ValidationErrorMessage if validation fails. Otherwise, null is returned.</returns>
    private IValidationMessage ValidateEmailIsNotEmpty(string failureMessage)
    {
        if (string.IsNullOrEmpty(this.Email))
        {
            return new ValidationErrorMessage(failureMessage);
        }

        return null;
    }

    private IValidationMessage ValidateEmailIsFormatted(string failureMessage)
    {
        string[] addressParts = this.Email.Split('@');

        if (addressParts.Length < 2)
        {
            var msg = new ValidationErrorMessage(failureMessage);
            return msg;
        }

        string[] domainPiece = addressParts.LastOrDefault().Split('.');
        if (domainPiece.Length < 2)
        {
            var msg = new ValidationErrorMessage(failureMessage);
            return msg;
        }

        return null;
    }

    /// < summary>
    /// Validates that the password is not empty.
    /// < /summary>
    /// < param name="failureMessage">The message to supply the error collection if validation fails.</param>
    /// < returns>Returns a ValidationErrorMessage if validation fails. Otherwise, null is returned.</returns>
    private IValidationMessage ValidatePasswordIsNotEmpty(string failureMessage)
    {
        if (string.IsNullOrEmpty(this.Password))
        {
            return new ValidationErrorMessage(failureMessage);
        }

        return null;
    }

    /// < summary>
    /// 
    /// < /summary>
    /// < param name="failureMessage">The message to supply the error collection if validation fails.</param>
    /// < returns>Returns a ValidationErrorMessage if validation fails. Otherwise, null is returned.</returns>
    private IValidationMessage ValidatePasswordIsToShort(string failureMessage)
    {
        if (this.Password.Length < 8)
        {
            return new ValidationErrorMessage(failureMessage);
        }

        return null;
    }

    /// < summary>
    /// Tests to see if the password contains any spaces.
    /// < /summary>
    /// < param name="failureMessage"></param>
    /// < returns></returns>
    private IValidationMessage ValidateIfPasswordContainsSpaces(string failureMessage)
    {
        if (this.Password.Contains(' '))
        {
            return new ValidationErrorMessage(failureMessage);
        }

        return null;
    }
}

View Model validation checks

This exposes validation methods to external objects as well. By inheriting from ValidatableBase, you can force validation checks on a model from within your view model.

    public bool CanExecute(object parameter)
    {
        // Perform validation on the user.
        this.AppUser.Validate();

        // Check if there are any errors.
        if (this.AppUser.HasValidationMessageType< ValidationErrorMessage>())
        {
            return false;
        }

        return true;
    }

Binding to the View

Binding to the view is really easy, using one of the two provided converters.

< Application.Resources>
    < converters:ValidationCollectionToSingleStringConverter x:Key="ValidationCollectionToSingleStringConverter" />
    < converters:IValidationMessageCollectionToStringCollectionConverter x:Key="CollectionConverter" />
< /Application.Resources>

Bind to a single error for a property.

< TextBlock x:Name="EmailValidationErrorTextBlock"
            Text="{Binding Path=AppUser.ValidationMessages[Email], 
                            Converter={StaticResource ValidationCollectionToSingleStringConverter}}"
            Foreground="Red" />

Bind to the entire collection of errors for a property

< ItemsControl ItemsSource="{Binding Path=AppUser.ValidationMessages[Password], 
                                    Converter={StaticResource CollectionConverter}}">
    < ItemsControl.ItemTemplate>
        < DataTemplate>
            < TextBlock Text="{Binding}"
                        Foreground="Red" />
        < /DataTemplate>
    < /ItemsControl.ItemTemplate>
< /ItemsControl>

Custom object validation in WinRT Universal Apps

I mentioned about a month ago that i was going to work on a task management app. Since the app is going to target both Windows Phone 8 and Windows 8, I thought it would make sense to make use of Microsoft's new Universal App set up. Unfortunately for me, this turned out to be a bigger challenge than I anticipated to get set up. I'll blog about the difficulties of setting the project up initially later, since it deals largly with Universal apps working with Prism, Unity and Mocking. Today, I'm going to go over one of the major things that the WinRT shared library is missing. Data Validation.

The big brother framework (WPF) contains an excellent set of tools for data validation. As does the Silverlight API. Microsoft has a lot of examples of working data validation in WinRT targeting Windows 8, but those all go out the door with a universal app supporting Windows Phone 8. So I built my own.

There are a number of ways you can approach this. To work through these examples, I have put together the following Account Creation View that the examples I show will be based on.

The XAML required to re-produce this is really straight forward. I centered a stack panel in a Grid row, put a couple TextBlocks and a couple TextBoxs along with a single Button. To keep things short on the blog, I will just provide the XAML required to display the account creation StackPanel.

< StackPanel Grid.Row="1"
            VerticalAlignment="Center"
            HorizontalAlignment="Center">

    < !-- E-Mail address input -->
    < TextBlock Text="Email"
                Style="{StaticResource TitleTextBlockStyle}" />
    < TextBox x:Name="EmailTextBox"
                Margin="0 5 0 0"
                MinWidth="200"
                Text="{Binding Path=Email, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
    < TextBlock x:Name="EmailValidationErrorTextBlock"
                Foreground="Red" />

    < !-- Password input -->
    < TextBlock Text="Password"
                Margin="0 30 0 0"
                Style="{StaticResource TitleTextBlockStyle}" />
    < TextBox x:Name="PasswordTextBox"
                Margin="0 5 0 0"
                MinWidth="{Binding ElementName=EmailTextBox, Path=MinWidth}"
                Text="{Binding Path=Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
    < TextBlock x:Name="PasswordValidationErrorTextBlock"
                Foreground="Red" />

    < !-- Login command button -->
    < Button Content="Create Account"
            Margin="0 10 0 0" />
</StackPanel>

Next, we need to create a model. The Model is simple and looks like this:

public class User : INotifyPropertyChanged
{
    private string email;
    private string password;

    public event PropertyChangedEventHandler PropertyChanged;

    public string Email
    {
        get { return email; }
        set 
        { 
            email = value;
            this.OnPropertyChanged("Email");
        }
    }
    public string Password
    {
        get { return password; }
        set 
        { 
            password = value;
            this.OnPropertyChanged("Password");
        }
    }
    protected void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Now we are ready to go.

Code-Behind

The first option available for performing validation is doing it in the code-behind using an event handler. We can modify our Button XAML to include an event handler like this:

< Button Content="Login"
         Margin="0 10 0 0"
         Click="Button_Click" />

Now each time the button is called, it will fire the event. If you're a WPF developer, or have been doing Windows 8 development for awhile, you're probably yelling "This isn't WinForms!". I hear your shouts and agree, but for the sake of demonstrating a possible approach, let's follow this through to the end.

Next we need to write the validation in the code-behind. Since we are not maintaining view state, or using an ICommand implementation, we don't need to set up a View Model for this scenario. Binding to the Model is just fine. We just need to set it as our DataContext via the View's constructor.

public LoginPage()
{
    this.InitializeComponent();
    this.DataContext = new User();
}

Now we implement our event handler for the Create User button being clicked. This will handle all of our validation.

private void Button_Click(object sender, RoutedEventArgs e)
{
    User user = this.DataContext as User;
    if (user.Password.Length < 8)
    {
        this.PasswordValidationErrorTextBlock.Text = "Password must be a minimum of 8 characters";
    } 
    if (user.Password.Length > 16)
    {
        this.PasswordValidationErrorTextBlock.Text = "Password can not exceed 16 characters.";
    }
    if (string.IsNullOrEmpty(user.Email))
    {
        this.EmailValidationErrorTextBlock.Text = "Email can not be left blank.";
    }
}

This makes me cry a little inside each time I see it. There should never be any validation in your Code-Behind. Ever. Why you ask? Let's break it down.

  1. Testability. With this in the View's code-behind, you can't test any of your business rules.
  2. Reusability. We are writing the Create User View. What about Logging back in with an existing user? You'll want to re-use the same model wouldn't you? Ideally have part of the same validation, such as the blank email address being checked? You'll have to re-write the validation in each View with this approach.
  3. Violates the MVVM pattern. You should have all of the business logic outside of the View. The code-behind can be used to handle View related things, but never business logic.

View Model

Another option is to put the validation in the View Model, and let the UI know what the errors are by binding to error properties. In order to show this, we need to first remove the code-behind and create our View Model. It would look like this.

public class AccountCreationViewModel : INotifyPropertyChanged, ICommand
{
    private string emailEmptyError;
    private string passwordToShortError;
    private string passwordToLongError;

    private User appUser;

    public event PropertyChangedEventHandler PropertyChanged;

    public User AppUser
    {
        get { return appUser; }
        set 
        { 
            appUser = value;
            this.OnPropertyChanged("AppUser");
        }
    }
    public string EmailEmptyError
    {
        get { return emailEmptyError; }
        set 
        { 
            emailEmptyError = value;
            this.OnPropertyChanged("EmailEmptyError");
        }
    }
    public string PasswordToShortError
    {
        get { return passwordToShortError; }
        set 
        { 
            passwordToShortError = value;
            this.OnPropertyChanged("PasswordToShortError");
        }
    }
    public string PasswordToLongError
    {
        get { return passwordToLongError; }
        set 
        { 
            passwordToLongError = value;
            this.OnPropertyChanged("PasswordToLongError");
        }
    }
    protected void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    public void Execute(object parameter)
    {
        if (AppUser.Password.Length < 8)
        {
            this.PasswordToShortError = "Password must be a minimum of 8 characters.";
            return;
        }

        if (AppUser.Password.Length > 16)
        {
            this.PasswordToLongError = "Password can not exceed 16 characters.";
            return;
        }

        if (string.IsNullOrEmpty(AppUser.Email))
        {
            this.EmailEmptyError = "Email can not be left blank.";
            return;
        }

        // Create the user
        // ......
    }
}

Already this is looking a bit hard to read. We are creating unnecessary properties in the View Model to keep track of validation errors. We would need to update our View to use the View Model as its data context along with updating the bindings on the TextBox's to bind to the ViewModel.AppUser object. We also need to bind our error TextBlocks to the error messages in the View Model

< Page.DataContext>
    < viewModels:AccountCreationViewModel />
< /Page.DataContext>

< TextBox x:Name="EmailTextBox"
            Margin="0 5 0 0"
            MinWidth="200"
            Text="{Binding Path=AppUser.Email, 
                           Mode=TwoWay, 
                           UpdateSourceTrigger=PropertyChanged}" />
< TextBox Margin="0 5 0 0"
          MinWidth="200"
          Text="{Binding Path=AppUser.Password, 
                           Mode=TwoWay, 
                           UpdateSourceTrigger=PropertyChanged}" />

< TextBlock Text="{Binding Path=PasswordToLongError}" 
            Foreground="Red"/>
< TextBlock Text="{Binding Path={PasswordToShortError}" 
            Foreground="Red"/>
< TextBlock Text="{Binding Path=EmailEmptyError}" 
            Foreground="Red"/>

Lastly, update our button so it fires the Excute method associated with the ICommand interface.

< Button Content="Create Account"
        Margin="0 10 0 0"
        Command="{Binding}" />

When the button is clicked, it will execute the command. The command will run through the business rules and update the error properties. Each time the error property is updated, the UI will reflect the errors.

This is still a bad approach to take. While this does make your code testable, your validation is still tightly coupled with your View (since each View should have their own View Model). It also continues to prevent your business logic from being reusable.

Custom validation in the Model

Now we get to the meat of this post. The validation should be placed in your Model object, so that your model is a complete object. It contains the properties it needs to do its job, it becomes self-validating and can be re-used through the app.

Moving our three error properties from the View Model in to the model is a bad idea however. The error properties are really used to assist the View in displaying errors and don't help the Model in any way. The model is already aware that it has validation issues. In WPF and WinRT for Windows 8 development, you would use INotifyDataErrorInfo. The View would be notified when a property validation error existed and could react accordingly. Unfortunately, we do not have that when you are building a Windows 8/Windows Phone Universal app. So I set out to create my own framework.

The first thing I did was created an interface that all models needing validation would be required to implement. I'll show the interface, then we will discuss it a bit further.

public interface IValidatable
{
    Dictionary< string, List< IValidationMessage>> ValidationMessages { get; }

    void AddValidationMessage(IValidationMessage message, string property = "");
    void RemoveValidationMessage(string message, string property = "");
    void RemoveValidationMessages(string property = "");
    bool HasValidationMessageType< T>(string property = "");
    IValidationMessage ValidateProperty(
        Func< string, 
        IValidationMessage> validationDelegate, 
        string failureMessage, 
        string propertyName = "");
}

So let's go over each method on by one.

ValidationMessages

This is a read-only property, that will contain all of our validation messages. The property has a Key typed to a string, which will be the Models property name. The value is a collection of IValidationMessage objects (We will discuss what the IValidationMessage is later). The idea being that for each property in the model, we can store more than 1 error.

AddValidationMessage(IValidationMessage message, string property = "");

This method is used to add a validation message to the ValidationMessages collection. The property will be assigned as the Key, with the message being added as the value.

RemoveValidationMesssage(IvalidationMessage message, string property = "");

Just like we can add a validation message, we will provide ourselves with the ability to remove it.

RemoveValidationMessages(string property = "");

We can use this method to completely clear out all validation messages in one shot for a single property.

HasValidationMessageType< T>(string property = "");

This method will return true if the object has validation messages matching < T> and false if it does not.

ValidateProperty(
    Func< string, 
    IValidationMessage> validationDelegate, 
    string failureMessage, 
    string propertyName = "");

This method can be called to actually perform validation on a property within the object and build the collection of errors. The arguments require a method delegate that returns an IValidationMessage object. This is how the validation becomes reusable. Each individual object can pass in a method delegate that performs the actual validation. The IValidatable implementation will take the results and determine if it must go in to the ValidationMessages collection or not.

IValidationMessage

It looks like a lot of the interface relies on a secondary interface called IValidationMessage doesn't it? This interface is really straight forward. It contains a single property called Message.

public interface IValidationMessage
{
    string Message { get; }
}

The idea with this, is that we can create objects that implement this interface, but containing different types of messages. For instance, in this post, we will create a ValidationErrorMessage and a ValidationWarningMessage. You could go on and create any kind of messaging you want and use it for binding to the View.

Implementing the IValidatable

Rather than having our User model implement this interface, we will implement it within a new Base class. We will call the class ValidatableBase.

public abstract class ValidatableBase : IValidatable, INotifyPropertyChanged
{
    private Dictionary< string, List< IValidationMessage>> validationMessages = 
        new Dictionary< string, List< IValidationMessage>>();
    public event PropertyChangedEventHandler PropertyChanged;
}

Our initial class contains the Dictionary that will hold our validation messages. Next, we implement the read-only property required by our interface.

public Dictionary< string, List< IValidationMessage>> ValidationMessages
{
    get
    {
        return this.validationMessages;
    }
    private set
    {
        this.validationMessages = value;
        this.OnPropertyChanged("ValidationMessages");
    }
}

The call to OnPropertyChanged will let the UI know that this collection has changed. This in most cases won't be used since the collection is read-only, but since it is going in to a base class, we want to provide support for that.

Next, we implement our HasValidationMessageType method.

public bool HasValidationMessageType< T>(string property = "")
{
    if (string.IsNullOrEmpty(property))
    {
        bool result = this.validationMessages.Values.Any(collection =>
            collection.Any(msg => msg is T));
        return result;
    }

    return this.validationMessages.ContainsKey(property);
}

In this method, we check if the collection contains a Key matching the property supplied. If it does, then we check it's values to see if any of them match the Type specified in < T>. This lets you do something like

HasValidationMessageType< ValidationErrorMessage>("Email");

to check if the model has a validation error on the email property.

The AddValidationMessage method is pretty easy as well.

public void AddValidationMessage(IValidationMessage message, string property = "")
{
    if (string.IsNullOrEmpty(property))
    {
        return;
    }

    // If the key does not exist, then we create one.
    if (!this.validationMessages.ContainsKey(property))
    {
        this.validationMessages[property] = new List< IValidationMessage>();
    }

    if (this.validationMessages[property].Any(msg => msg.Message.Equals(message.Message) || msg == message))
    {
        return;
    }

    this.validationMessages[property].Add(message);
}

In this method we create a new collection if the key doesn't exist yet, we then double check to ensure this validation message does not already exist in the collection. If not, we add it.

The two Removal methods are easy enough as well.

public void RemoveValidationMessage(string message, string property = "")
{
    if (string.IsNullOrEmpty(property))
    {
        return;
    }

    if (!this.validationMessages.ContainsKey(property))
    {
        return;
    }

    if (this.validationMessages[property].Any(msg => msg.Message.Equals(message)))
    {
        // Remove the error from the key's collection.
        this.validationMessages[property].Remove(
            this.validationMessages[property].FirstOrDefault(msg => msg.Message.Equals(message)));
    }
}

Here we just check if there is any message for the supplied Key and remove it. At the moment, this does not do any Type checking to see if there is more than one Type of object (Warning and Error) in the collection with the same message. The method just removes the first thing it finds and calls it good.

Removing the entire property from the collection is even easier.

public void RemoveValidationMessages(string property = "") 
  {
      if (string.IsNullOrEmpty(property))
      {
          return;
      }

      if (!this.validationMessages.ContainsKey(property))
      {
          return;
      }

      this.validationMessages[property].Clear();
    this.validationMessages.Remove(property);
}

We just check if a key exists that matches the property name and then clear out its messages contents and remove the key from the Dictionary.

Finally, we finish implementing the interface by building the ValidateProperty method. In this method, we just invoke the delegate we are provided, and accept a IValidationMessage object in return. If the return value is not null, then we add it to the ValidationMessages collection. If it is null, then we can assume that the validation passed and there are no issues. Since that is the case, we remove it from the validation collection.

public IValidationMessage ValidateProperty(
    Func< string, 
    IValidationMessage> validationDelegate, 
    string failureMessage, 
    string propertyName = "")
{
    IValidationMessage result = validationDelegate(failureMessage);
    if (result != null)
    {
        this.AddValidationMessage(result, propertyName);
    }
    else
    {
        this.RemoveValidationMessage(failureMessage, propertyName);
    }

    return result;
}

We have satisfied the requirements of the IValidatable interface, but there is one more method we need to add to the base class. This will let us group all of our property validations in to a single call.

public abstract void Validate();

We mark it as abstract, since the base class has nothing to validate, and we want to force any object that inherits from the base class to implement the method. If you don't want to do this, you can opt out of in your code. Not everyone needs to have this feature, thus the reason why it was left out of the interface.

Also, our base class implements the INotifyPropertyChanged method, so we will remove it from our model and put the implementation in to our base class.

public void OnPropertyChanged(string propertyName)
{
    if (this.PropertyChanged != null)
    {
        this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

Revisiting our Model

Finally, we can revisit the model and add our fancy new validation. The first thing we have to do is change our class declaration. Initially, we implemented the INotifyPropertyChange interface, but since our base class implements this, we don't need to now. We just need to inherit from our base class.

public class User : ValidatableBase

Now that we are inheriting from our base class, we need to implement the required Validate() method. In order to keep with the Single-Responsibility-Principle, we will invoke other methods from within the Validate() method. Since we have to validate multiple properties, we should have each property validation be contained within it's own method. This makes it easier to test.

public override void Validate()
{
    this.ValidatePassword("Password");
    this.ValidateEmail("Email");

    // Passing in an empty string will cause the ValidatableBase indexer to be hit.
    // This will let the UI refresh it's error bindings.
    base.OnPropertyChanged(string.Empty);
}

Here we just invoke a ValidatePassword and ValidateEmail method. When we are done, we notify any observers that the entire object has changed by not specifying a property name in the call to OnPropertyChanged. This lets the observers (in this case, the View) know its bindings need to be refreshed.

public IValidationMessage ValidatePassword(string property)
{
    const string passwordToShortError = "Password must a minimum of 8 characters in length.";
    const string passwordToLongError = "Password must not exceed 16 characters in length.";
    if (this.Password.Length < 8)
    {
        var msg = new ValidationErrorMessage(passwordToShortError);
        return msg;
    }
    if (this.Password.Length > 16)
    {
        var msg = new ValidationErrorMessage(passwordToLongError);
        return msg;
    }

    return null;
}

public IValidationMessage ValidateEmail(string property)
{
    const string emailAddressEmptyError = "Email address can not be blank.";
    if (string.IsNullOrEmpty(this.Email))
    {
        var msg = new ValidationErrorMessage(emailAddressEmptyError);
        return msg;
    }
}

Now our model has proper validation. It is testable and reusable. Much, much better. Next, we need to revise our View Model. We will delete all of the error properties within it, along with the INotifyPropertyChanged implementation. We will only need the AppUser property and the ICommand implementation.

public class LoginPageViewModel : ICommand
{
    public LoginpageViewModel()
    {
        this.AppUser = new User();
    }

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        this.AppUser.Validate();

        if (this.AppUser.HasValidationMessageType< ValidationErrorMessage>())
        {
            return;
        }

        // Create the user.
    }
}

We now have one more thing to do. We need to update our XAML. The Error TextBlocks will now bind to the ValidationMessages property within the model, using an index matching the property they are bound to.

<TextBlock data-preserve-html-node="true" data-preserve-html-node="true" Text="{Binding Path=AppUser.ValidationMessages[Password], 
                            Converter={StaticResource ValidationMessageConverter}}" 
            Foreground="Red"/>
<TextBlock data-preserve-html-node="true" data-preserve-html-node="true" x:Name="EmailValidationErrorTextBlock"
            Text="{Binding Path=AppUser.ValidationMessages[Email], 
                            Converter={StaticResource ValidationMessageConverter}}"
            Foreground="Red" />

You can see in this XAML that I am using a value converter when binding to the collection. That is because the binding is to an implementation of IValidationMessage. The UI does not know how to render this, so rather than overriding the ToString() method on each IValidationMessage implementation, I wrote a Value Converter.

public class ValidationMessageConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        if (!(value is IEnumerable< IValidationMessage>))
        {
            return string.Empty;
        }

        var collection = value as IEnumerable< IValidationMessage>;
        if (!collection.Any())
        {
            return string.Empty;
        }

        return collection.FirstOrDefault().Message;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

Now, when you run the app and enter an invalid Email or Password, the UI will automatically inform you of the validation errors when you press the Create Account button. If you ever need to add more Email validation (such as the proper email format) or more Password validation (such as not allowing specific characters) you can do so without needing to modify your View Model or your View.

If you need to add a whole new property to the Model, with validation, you can. You don't need to modify your View Model, you only need to add a TextBlock to the View to display the validation.

Before we end the post, I will show you two implementations of the IValidationMessage. They both do the same thing, but are Typed differently so that you can segregate your messages by Type. This gives more flexibility that using an Enum.

First is the Error validation message.

public class ValidationErrorMessage : IValidationMessage
{
    public ValidationErrorMessage() : this(string.Empty)
    { }

    public ValidationErrorMessage(string message)
    {
        this.Message = message;
    }

    public string Message { get; private set; }
}

Next is the Warning validation message.

public class ValidationWarningMessage : IValidationMessage
{
    public ValidationWarningMessage() : this(string.Empty)
    { }

    public ValidationWarningMessage(string message)
    {
        this.Message = message;
    }

    public string Message { get; private set; }
}

You can now potentially create a ItemsControl in your XAML, bind it to the ValidationMessages collection and build a DataTemplate for each IValidationMessage implementation, each with different styles applied. So you could have orange TextBlocks for Warnings and Red for Errors.

I hope you guys find this useful while building Windows 8/Windows Phone 8 Universal apps!

The best task management solution.

I have been looking for the best way to manage my tasks from day to day. I've used simple apps like Todo, Toodledo, Google Tasks and Todo.txt. I've tried pro-apps like Omnifocus and Pocket Informant. None of which have been the perfect solution for me.

The issue I have had is that the pro apps are usually associated with a single operating system. Pocket Informant and Omnifocus both work on iOS and OS X, but neither on Windows. Todo.txt works great but it syncs through cloud services. All of which I can't access from my day job. The other task tools just don't have the functionality that I need.

So I guess it's time to start work on a new project. I've actually already got a massive portion of it completed, but it's not quiet ready for use yet. I am working on a new task management app that will run on Windows 7, Windows 8 Desktop, Windows 8 App Store, Windows Phone and hopefully make its way over to iOS, OS X and Android. As work on the project progresses, I'll be posting updates and screenshots on what it does and how it'll work.

Command & State management in Mud Designer

The previous version of the Mud Designer had a pretty good State system. The user would enter a command, the command would perform an action and the state would render the results to the screen. I spent a lot of time over the last couple of weekends trying to refactor the state system and add a couple new features.

Command Searching

I provided the player with a StateManager property, that the object can now access. This is used to try and find a command suitable to what the user typed, and execute it. In the new version of the Mud Designer, the delegate for receiving the user input, will call StateManager.PerformCommand which will try to find a command that can be used.

There are several ways that a Command can be found and executed. The manager makes an attempt to see if the command is stored in a collection of commands that the player owns. If it is, then the command is executed. If not, then the manager checks to see if the command has any short hand attributes. A command can be decorated with a short hand like this:

[ShorthandNameAttribute("Walk", "mv")]
public class WalkCommand : ICommand
{
}

This allows the actual command name, to vary from that of the class name. While you can provide any name, it is strongly recommended that builders implementing their own commands stick with a convention that the Mud Designer uses. That convention is to name your Command, with the command word appended. Like LookCommand, WalkCommand, TellCommand etc. With the attribute, you can shorten the name to just Look, Walk or Tell. You can shorten the name even further using the secondary argument. The three aforementioned commands can be shortend to l, w and t if you want to.

If no command is found matching our convention (user enters Walk, so we look for WalkCommand), then the manager will check all of the commands for a ShorthandNameAttribute. The ones that contain this attribute are checked. If any of them have a command name or shortened command that match the users input, then we have a match. Otherwise we continue our search.

The Stack.

The manager now has a Stack for commands. If a command is not completed, it pushes the command on to the stack and resumes control to the players individual game loop. If the command is completed, the command is popped off of the stack.

Once the manager has failed to find a command that matches the input provided by the user, it hits up the stack. If the stack contains a command, it pops it off and executes the command.

When a command's .Execute() method is finished, it can set a IsIncomplete property to true. If the property is set to true, it lets the State Managerk now that the command still has more steps to perform before it is really finished. Something like a User Login might require multiple steps (username and password entry). While it is possible to fetch the data directly from the user while in the command, this is now frowned on as it holds the thread up. It is better to return control to the caller and wait for the user to enter data in to the main player loop. When the new data is entered, the State Manager will pass that data back to the same command, which can then finish off what it needs to.

When a command is marked as incomplete, it is pushed on to the stack. When the command is executed, it is popped off of the stack. Only commands that must be preserved for additional actions are placed in the stack.

Example Command:

The following is an example of a single action command.

using System;
using MudEngine.Engine.Core;
using MudEngine.Engine.Networking;

namespace MudEngine.Engine.Commands
{
    [ShorthandName("Disconnect", "/dc")]
    public class DisconnectCommand : ICommand
    {
        public string CommandInput { get; private set; }

        public bool IsIncomplete { get; }

        public void Execute(GameObjects.Mob.IMob mob, string input)
        {
            if (mob is ServerPlayer)
            {
                var player = mob as ServerPlayer;

                mob.Send(new InformationalMessage("Disconnecting."));
                player.Disconnect();
            }
        }
    }
}

Pretty straight forward. You can see how we set our shorthand names, send a message to the player that we are disconnecting and then disconnect them. The player can type Disconnect or /DC and the game will disconnect them from the server.

Example Command with State

Now we want to maintain state in our command. Let's create a simple "Provide your name and age" command used during character creation.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MudEngine.Engine.Core;
using MudEngine.Engine.GameObjects.Mob.States;
using MudEngine.Engine.Networking;

namespace MudEngine.Engine.Commands
{
    public class CreateCharacterCommand : ICommand
    {
        int state = 0; // 0 = uninitialized; 1 = username entered, 2 = age entered.
        public string CommandInput { get; private set; }

        public bool IsIncomplete { get; private set; }

        public void Execute(GameObjects.Mob.IMob mob, string input)
        {
            // First execution of the method.
            if (!this.IsIncomplete)
            {
                state = 0;
                mob.Send(new InputMessage("Please enter your name"));
                this.IsIncomplete = true;
                mob.StateManager.SwitchState< ReceivingInputState>();
            }
            else if (this.state == 0)
            {
                this.CommandInput = input;
                mob.Send(new InformationalMessage(string.Format("Hello {0}", this.CommandInput)));
                mob.Send(new InputMessage("Please enter your age"));
                this.IsIncomplete = true;
                this.state = 1;
                mob.StateManager.SwitchState< ReceivingInputState>();
            }
            else
            {
                // Out put the age from current input along with name from previous command input.
                mob.Send(new InformationalMessage(string.Format("You are {0}s old {1}", input, this.CommandInput)));
                this.IsIncomplete = false;
                this.state = 2;
                mob.StateManager.SwitchState< LookState>();
            }
        }
    }
}

As you can see in here, we maintain some simple state to determine where in our user data input state we are. The state manager will execute this command once, then determine that it is not completed and push it to the stack. When the user enters "Bob" for a user name, the State Manager will not find a command matching "Bob" and will pop the previous command off the stack and execute it.

The benefit here is that the player can type "Help", which the state manager will find. So the user can be in the middle of a command, and piggy back on top of it to execute another. This will work really well going forward and allow for some complex command chaining as well.

Conclusion

While commands at the moment can be executed without a ShothandNameAttribute decorated on the class, I am considering making this a requirement. By requiring all commands be given at least a name (shorthand version optional), I can allow the engine (and the commands wrote for it) to execute internal commands. A "CreateCharacter" command would not be executable from a user, since there are now ShorthandNameAttributes associated with it. Yet, your Login command could request that the players StateManager perform the command.

mob.StateManager.PerformCommand(new ReceivedInputMessage("CreateCharacter"));

This isn't wrote in to the engine yet, but this is something I am considering before shipping.

IDataErrorInfo in WPF Apps

I had been using IDataErrorInfo implementations in all of my view models when writing WPF apps in order to perform property validation for the view. It's worked really well, with a couple of exceptions.

  1. Sticking it in my view models usually results in a really long indexer, as I perform validation on all of the properties in my view model.
  2. Prevents the validation from being re-used across multiple view models. While in some cases, validation is view specific, there are certainly times were validation is object specific (and not view specific), in which I could re-use it in multiple places.

We have made it roughly 50% of the way through our app at work when I ran across a post on MSDN Social that essentially clarified things for me. Unfortunately, it means a pretty heft change to our overall app and I don't know if the time required to migrate all of the object level validation down to the models right now is justifiable. At some point I really think we should make the change, since it would probably help make things easier to trace in the future during debugging.

Having all of the validation contained within the model makes sense. You could then use the CanExecute method in the ICommand to ensure business rules are met prior to allowing actions to take place. Other business rules related to a combination of values could be applied within the view model, either using an implementation of IDataErrorInfo or a child of ValidationRule.

So my lesson learned for the day is, validation in POCO classes are alright, and in most cases encouraged.