Для презентации, включающей шесть компонентов PersonName объекта Person, я добавил расширение и «мини-модель представления» (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» и значение метки, и позволить модели мини-вида установить соответствующий метод получения / установки делегаты, что-то вроде:
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;
}
}