I will give you an answer that you do not want to hear: you do not need to do this at all. Your model should have properties (full or automatic), and then your ViewModel properties should only have a receiver and setter that returns _model.MyProperty .
Alternatively, you might want to look into CallerMemberName to get rid of this annoying magic line. If you want, I will post some examples.
For example, I have a class for the DealsUser model (note how internal logic is done, for example, generating an email address if it has never been explicitly set):
public class DealsUser : IDealsUser { public DealsUser() : this("GUEST") { } public DealsUser(string username) { this.Username = username; this.IsAdministrator = false; this.IsPlanModerator = false; this.IsPlanner = false; } public string Username { get; set; } public bool IsAdministrator { get; set; } public bool IsPlanModerator { get; set; } public bool IsPlanner { get; set; } private string _emailAddress; public string EmailAddress { get { return _emailAddress ?? string.Format( "{0}@mycompany.co.za", this.Username); } set { _emailAddress = value; } } public override string ToString() { return this.Username; }
And I have a BaseViewModel class with the following events and protected methods (note how we use CallerMemberName to remove magic strings):
#region INotifyPropertyChanged Members public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { var eventHandler = this.PropertyChanged; if (eventHandler != null) { eventHandler(this, new PropertyChangedEventArgs(propertyName)); } } protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null) { if (object.Equals(storage, value)) { return false; } storage = value; this.OnPropertyChanged(propertyName); return true; } protected bool SetModelProperty<T>(T storage, T value, Action setter, [CallerMemberName] string propertyName = null) { if (object.Equals(storage, value)) { return false; } setter(); this.OnPropertyChanged(propertyName); return true; }
Then I inherit from BaseViewModel , I am dependent, add the model to my constructor, and I try to keep my ViewModel as small as possible . Note that I should use SetModelProperty instead of SetProperty , because you cannot pass a property (e.g. _dealsUser.Username ) to the lamba function as a reference variable. Also note that IsPlanner and IsPlanModerator contain additional logic that updates the associated notification properties when they change:
public class DealsUserVM : BaseViewModel { private readonly IDealsUser _dealsUser; public DealsUserVM() : this(new DealsUser()) { // Empty ctor } public DealsUserVM(IDealsUser dealsUser) { _dealsUser = dealsUser; } public IDealsUser Model { get { return _dealsUser; } } public string Username { get { return _dealsUser.Username; } set { SetModelProperty(_dealsUser.Username, value, () => { _dealsUser.Username = value; }); } } public bool IsAdministrator { get { return _dealsUser.IsAdministrator; } set { SetModelProperty(_dealsUser.IsAdministrator, value, () => { _dealsUser.IsAdministrator = value; }); } } public bool IsPlanModerator { get { return _dealsUser.IsPlanModerator; } set { // If IsPlanModerator has changed (and was updated as a result) if (SetModelProperty(_dealsUser.IsPlanModerator, value, () => { _dealsUser.IsPlanModerator = value; })) { // If IsPlanModerator is now TRUE if (value) { this.IsPlanner = true; } } } } public bool IsPlanner { get { return _dealsUser.IsPlanner; } set { // If IsPlanner has changed (and was updated as a result) if (SetModelProperty(_dealsUser.IsPlanner, value, () => { _dealsUser.IsPlanner = value; })) { // If IsPlanner is now FALSE if (!value) { this.IsPlanModerator = false; } } } } public string EmailAddress { get { return _dealsUser.EmailAddress; } set { SetModelProperty(_dealsUser.EmailAddress, value, () => { _dealsUser.EmailAddress = value; }); } } public override string ToString() { return _dealsUser.ToString(); } }
Hope this helps :-)