2017-11-30 2 views
0

프리즘 MVVM을 처음 사용하고 모델의 프로퍼티를 지원하는 ViewModel 프로퍼티를 생성하려고합니다.Prism MVVM ViewModel 프로퍼티 backing 필드를 모델의 프로퍼티로 사용

public class SomeViewModel : BindableBase, INavigationAware 
    { 
     private Person model; 
     public Person Model 
     { 
      get { return model; } 
      set { SetProperty(ref model, value); } 
     } 

     public string DisplayName 
     { 
      get { return Model.DisplayName; } 
      set { SetProperty(ref Model.DisplayName, value); } 
     } 

는하지만 줄에서 컴파일러 오류가 발생

set { SetProperty(ref Model.DisplayName, value); } 

"A 속성 또는 인덱서는 아웃 또는 심판 매개 변수로 전달되지 않을 수 있습니다."

그럼 어떻게해야합니까?

답변

2

OnPropertyChanged를 수동으로 높이고 도우미없이 설정해야합니다.

public string DisplayName 
    { 
     get { return Model.DisplayName; } 
     set 
     { 
      Model.DisplayName = value; 
      OnPropertyChanged(); 
     } 
    } 
+1

그렇다면 값이 다른지 수동으로 확인해야합니까? 공용 문자열 DisplayName { get {return Model.DisplayName; } 세트 { if (Model.DisplayName! = value) { Model.DisplayName = value; OnPropertyChanged(); } } } –

+0

일반적으로 값이 실제로 변경 될 때만 propertychanged 이벤트가 발생하므로 예상을 확인해야합니다. 그러나 데이터 바인딩의 경우에는 아무런 차이가 없습니다. – Liero

1

당신은 Reflection를 사용하고 Prism.Mvvm.BindableBase에서 상속 BindableBaseExtended 같은 것을 만들 수 있습니다.

public class SomeViewModel : BindableBaseExtended 
{ 
    private Person model; 
    public Person Model 
    { 
     get { return model; } 
     set { SetProperty(ref model, value); } 
    } 
    public string MyProperty 
    { 
     get { return Model.DisplayName; } 
     set { SetProperty(Model, m => m.DisplayName, value); } 
    } 
} 

public class BindableBaseExtended : BindableBase 
{ 
    protected virtual bool SetProperty<TClass, TMember>(TClass target, Expression<Func<TClass, TMember>> expression, TMember value, [CallerMemberName] string propertyName = null) 
    { 
     var expr = (MemberExpression)expression.Body; 
     var prop = (PropertyInfo)expr.Member; 
     var propValue = prop.GetValue(target, null); 
     if (object.Equals(propValue, value)) return false; 

     prop.SetValue(target, value, null); 
     this.RaisePropertyChanged(propertyName); 
     return true; 
    } 
    protected virtual bool SetProperty<TClass, TMember>(TClass target, Expression<Func<TClass, TMember>> expression, TMember value, Action onChanged, [CallerMemberName] string propertyName = null) 
    { 
     var expr = (MemberExpression)expression.Body; 
     var prop = (PropertyInfo)expr.Member; 
     var propValue = prop.GetValue(target, null); 
     if (object.Equals(propValue, value)) return false; 

     prop.SetValue(target, value, null); 
     onChanged?.Invoke(); 
     this.RaisePropertyChanged(propertyName); 
     return true; 
    } 
} 
+0

물론 BindableBase를 확장하고 BindableBase 클래스를 만들 수는 있지만 리플렉션을 사용하지 않으면 어떤 방법이 있습니까? –

+0

Reflection을 사용하지 않으려면 Model 속성을 래핑 할 수 있도록 각 ViewModel 속성에 BindableBase.SetProperty의 논리를 구현해야합니다. 그러나 가독성을 선호한다면이 방법이 좋습니다. –