对于涉及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 /塞特代表,如:
LastName = new PersonNamePropertyTextBox(vm=>LastName, PeopleResources.LastName_Label);
我正在努力解决如何做到这一点。有什么想法吗?
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);
}
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;
}
}
答案 0 :(得分:1)
尝试实现binder类来管理绑定。在这种情况下,我使用了PropertyBinding
。
public class PropertyBinding
{
public static PropertyBinding To(ViewModel vm, Name name, string label)
{
return new PropertyBinding { ViewModel = vm, Getter = new Func<string>(delegate() { return name.Value; }), Setter = new Action<string>(delegate(string value) { name.Value = value; }), Label = label };
}
public string Label { get; set; }
public ViewModel ViewModel { get; set; }
public Func<string> Getter { get; set; }
public Action<string> Setter { get; set; }
public string Value
{
get { return this.Get(); }
set { this.Set(value); }
}
internal string Get()
{
// Implement UpdatePersonNamePropert here.
// Maybe convert culture before returning.
return this.Getter();
}
internal void Set(string value)
{
// Maybe convert culture before storing.
this.Setter(value);
}
}
它会被称为:
LastName = new PersonNamePropertyTextBox(PropertyBinding.To(Model, Model.GetPersonName().LastName, PeopleResources.LastName_Label));
请注意Model.GetPersonName().LastName
必须返回指针类型而不是值类型,否则在调用Setter时无法更新LastName。例如:
public sealed class Name
{
public string Value { get; set; }
}
在此示例中,PersonName实现如下,但您的实施可能不同。
public class PersonName
{
public Name LastName { get; set; }
public Name FirstName { get; set; }
}
如果没有所有类信息以及与您使用的某些变量相关联的强类型,则很难验证,但我认为这应该可以帮助您摆脱困境。
希望这有帮助。