我会给你一个你不想听到的答案:你根本不需要这样做。您的模型应该具有(完整或自动)属性,然后您的 ViewModel 属性应该只有一个 getter 和一个返回的 setter _model.MyProperty
。
此外,您可能想研究CallerMemberName
摆脱那个讨厌的魔法字符串。如果您愿意,我会发布一些示例。
例如,我有一个DealsUser
模型类(请注意,如果从未明确设置过,如何生成电子邮件地址等内部逻辑在此处完成):
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;
}
我有一个BaseViewModel
带有以下事件和受保护方法的类(注意我们如何使用CallerMemberName
消除魔术字符串):
#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;
}
#endregion
然后我继承自BaseViewModel
,我将模型依赖注入到我的构造函数中,并尝试使我的 ViewModel尽可能精简。请注意,我必须使用SetModelProperty
而不是SetProperty
,因为您不能将属性(例如_dealsUser.Username
)作为参考变量传递给 Lamba 函数。还要注意IsPlanner
并IsPlanModerator
包含额外的逻辑,当它们发生变化时更新相关的通知属性:
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();
}
}
希望这可以帮助 :-)