Creating a view model with a model

This example shows how to create a “classical” view model without any Catel specific MVVM features such as data pass-through. Although it is recommended to use the pass-through features, some people want to have custom validation on the view model, or want to be fully in control.

Code snippets

Explanation

To be in full control, the only thing required is to create a basic view model with the vm code snippet. Then, the following methods should be implemented:

Code

C#

/// <summary>
/// Classical view model.
/// </summary>
public class ClassicalViewModel : ViewModelBase
{
   #region Properties
   /// <summary>
   /// Gets or sets the Person.
   /// </summary>
   private Person Person
   {
      get { return GetValue<Person>(PersonProperty); }
      set { SetValue(PersonProperty, value); }
   }

   /// <summary>
   /// Register the Person property so it is known in the class.
   /// </summary>
   public static readonly PropertyData PersonProperty = RegisterProperty("Person", typeof(Person));

   /// <summary>
   /// Gets or sets the first name.
   /// </summary>
   public string FirstName
   {
      get { return GetValue<string>(FirstNameProperty); }
      set { SetValue(FirstNameProperty, value); }
   }

   /// <summary>
   /// Register the FirstName property so it is known in the class.
   /// </summary>
   public static readonly PropertyData FirstNameProperty = RegisterProperty("FirstName", typeof(string));

   /// <summary>
   /// Gets or sets the last name.
   /// </summary>
   public string LastName
   {
      get { return GetValue<string>(LastNameProperty); }
      set { SetValue(LastNameProperty, value); }
   }

   /// <summary>
   /// Register the LastName property so it is known in the class.
   /// </summary>
   public static readonly PropertyData LastNameProperty = RegisterProperty("LastName", typeof(string));
   #endregion

   #region Methods
   /// <summary>
   /// Initializes the object by setting default values.
   /// </summary>   
   protected override void Initialize()
   {
      // Get the person from (in this case) a magical context
      Person = Context.CurrentPerson;
 
      // Load the data manually to the view model
      FirstName = Person.FirstName;
      LastName = Person.LastName;
   }

   /// <summary>
   /// Validates the field values of this object. Override this method to enable
   /// validation of field values.
   /// </summary>
   /// <param name="validationResults">The validation results, add additional results to this list.</param>
   protected override void ValidateFields(List<FieldValidationResult> validationResults)
   {
       if (string.IsNullOrWhiteSpace(FirstName))
       {
           validationResults.Add(FieldValidationResult.CreateError(FirstNameProperty, "First name is required"));
       }
 
       if (string.IsNullOrWhiteSpace(LastName))
       {
           validationResults.Add(FieldValidationResult.CreateError(LastNameProperty, "Last name is required"));
       }
   }

   /// <summary>
   /// Saves the data.
   /// </summary>
   /// <returns>
   ///    <c>true</c> if successful; otherwise <c>false</c>.
   /// </returns>   
   protected override Task<bool> Save()
   {
      return Task.Factory.StartNew(() =>
      {
          // Save the data manually to the model
          Person.FirstName = FirstName;
          Person.LastName = LastName;
 
          // Save the model
          return Person.Save();
      });
   }
   #endregion
}

Have a question about Catel? Use StackOverflow with the Catel tag!


Discussion