2011-09-23 7 views
3

Person 개체의 PersonName의 6 개 구성 요소가 포함 된 프레젠테이션의 경우 중복 코드를 줄이고 데이터 바인딩을 용이하게하기 위해 확장명과 '미니보기 모델'(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 = new PersonNamePropertyTextBox(vm=>LastName, PeopleResources.LastName_Label); 

: 즉, "성"과 레이블 값 및하자 미니 뷰 모델은 적절한 게터/세터 대표, 뭔가를 설정합니다. 어떤 아이디어?

확장 바인딩을 관리하기 위해 바인더 클래스를 구현 시도해보십시오으로 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; 
    } 
} 
+0

왜 반사를 방지 하시겠습니까? – CodesInChaos

+2

@CodeInChaos : 재미있는 질문이지만, 나는 교통 체증과 비슷한 반사를 피하려고합니다. 나는 교통량이 많은 곳에서 운전하는 것을 싫어하지만 때로는 당신이해야 할 일이 있습니다. ... –

+1

@CodeInChaos, 모든 것이 평등합니다 - 즉, 문제를 똑같이 잘 해결할 수 있고 반사없이 해결할 수 있다면 - 사용하지 않는 해결책 반사가 더 안전하기 때문에 반사가 좋습니다. –

답변

1

의 일부 속성에 대해

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를 갱신 처리). 이 경우에는 PropertyBinding을 사용했습니다. Model.GetPersonName().LastName이 포인터 타입이 아닌 세터가 호출 될 때, 그렇지 않으면 성 업데이트 할 수없는 값 형식을 반환해야 함을 유의하시기 바랍니다

LastName = new PersonNamePropertyTextBox(PropertyBinding.To(Model, Model.GetPersonName().LastName, PeopleResources.LastName_Label)); 

:

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); 
    } 
} 

는처럼 호출 할 것입니다. 예를 들면 다음과 같습니다.

public sealed class Name 
{ 
    public string Value { get; set; } 
} 

이 예제에서는 PersonName이 다음과 같이 구현되었지만 구현이 다를 수 있습니다. 당신이 그것을 확인하기 힘들었다하지만이 문제에서 당신을 얻을해야한다고 생각 사용되는 변수의 일부와 관련된 모든 클래스 정보와 강한 유형없이

public class PersonName 
{ 
    public Name LastName { get; set; } 

    public Name FirstName { get; set; } 
} 

.

희망이 도움이됩니다.

+0

안녕하세요 버니, 이건 제가 교장 선생님에게 요구 한 것과 정확히 일치합니다. 예를 들어, Model.GetPersonName(). LastName은 요청 된 Name 매개 변수에 대한 인수로 컴파일되지 않습니다. 이름이 표시되지 않은 어딘가에서 new'd 래퍼가되어야하나요? PropertyBinding은 당신이 만든 클래스일까요, 아니면 프레임 워크의 어떤 것과 관련이 있습니까 (동적입니까?). 내가 뭘 놓치고 있니? – Berryl

+0

아 그래, 문제가 생겼어. GetPersonName() 및 PersonName 형식을 게시 할 수 있습니까? 이상적으로 당신은 과거에 어떻게했는지 인터페이스를 통해 PersonName에 Get/Set 함수를 구현할 것입니다. PropertyBinding은 단지 사용자 정의 클래스입니다. –

+0

전체 구현을 알지 못하는 PersonName 모델을 구현 한 방법은 내 업데이트를 참조하십시오. –

관련 문제