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
- vm - declare a view model
- vmprop - declare a property on a view model
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:
- Constructor - initialize the properties on the view model
- ValidateFields - check for field errors in the view model
- ValidateBusinessRules - check for business rules in the view model
- Save - save the view model data to the model and then save the model
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
}
Contributions
We would like to thank the following contributors:
Want to contribute to the documentation? We have a guide for that!
Questions
Have a question about Catel? Use StackOverflow with the Catel tag!