【发布时间】:2011-09-23 20:26:40
【问题描述】:
对于涉及 Person 对象的 PersonName 的六个组件的演示文稿,我添加了一个扩展和一个“迷你视图模型”(PersonNamePropertyTextBox),以减少重复代码并促进数据绑定。
所以在父视图模型的构造函数中,我创建了这些迷你视图模型:
public PimDetailVm(Person person, ..)
{
LastName = new PersonNamePropertyTextBox(
() => Model.GetPersonName().LastName, v => this.UpdatePersonNameProperty(pn => pn.LastName, v))
{
Label = PeopleResources.LastName_Label
};
FirstName = new PersonNamePropertyTextBox(
() => Model.GetPersonName().FirstName, v => this.UpdatePersonNameProperty(pn => pn.FirstName, v))
{
Label = PeopleResources.FirstName_Label
};
... etc.
}
public PersonNamePropertyTextBox LastName { get; private set; }
public PersonNamePropertyTextBox FirstName { get; private set; }
我现在真正想要的是能够做的只是传入当前属性,即“LastName”和标签值,并让迷你视图模型设置适当的Getter/ Setter 委托,类似于:
LastName = new PersonNamePropertyTextBox(vm=>LastName, PeopleResources.LastName_Label);
我正在为如何做到这一点而苦苦挣扎。有什么想法吗?
扩展(处理更新模型中的 PersonName)
public static void UpdatePersonNameProperty(this PimDetailVm vm, Expression<Func<PersonName, object>> propertyExpression, string value)
{
var pn = vm.Model.GetPersonName();
var pnProps = pn.GetType().GetProperties();
var subj = ExprHelper.GetPropertyName(propertyExpression);
var subjProp = pnProps.Single(pi => pi.Name.Equals(subj));
var currentVal = subjProp.GetValue(pn, null);
// split if there is nothing to update
if(currentVal==null && value==null) return;
if (currentVal != null && currentVal.Equals(value)) return;
// update the property
var capitalized = value == null ? null : value.Capitalize();
subjProp.SetValue(pn, capitalized, null);
// update the model
vm.Model.SetName(pn);
// broadcast the update
vm.NotifyOfPropertyChange(subj, value);
}
PersonName 的某些属性的迷你视图模型
public class PersonNamePropertyTextBox : TextBoxActionData
{
public PersonNamePropertyTextBox(Func<string> getterFunc, Action<string> setterAction) {
if (getterFunc == null) throw new ArgumentNullException("getterFunc");
if (setterAction == null) throw new ArgumentNullException("setterAction");
GetterFunc = getterFunc;
SetterAction = setterAction;
}
}
【问题讨论】:
-
为什么要避免反射?
-
@CodeInChaos:有趣的问题,我尽量避免像堵车一样的反射。我不喜欢在繁忙的交通中开车,但有时你只需要...
-
@CodeInChaos,所有事情都是平等的——也就是说,如果你可以在有和没有反射的情况下同样好地解决一个问题——不使用反射的解决方案更好,因为它更安全。
-
我不确定你是否可以在没有反射的情况下做到这一点,但是有一种方法可以使用委托更快地进行反射。看看这个链接,msmvps.com/blogs/jon_skeet/archive/2008/08/09/…
-
静态反射已经很安全了。当然,如果没有反射的代码与具有反射的代码具有相似的复杂性,那么我会避免它。但是反射的缺点,如果做得好,是非常小的。
标签: c# reflection mvvm expression-trees