2017-11-30 32 views
0

私はPrism MVVMを初めて使用し、モデルのプロパティのバッキングフィールドを持つViewModelプロパティを作成しようとしています。モデルのプロパティとしてPrism MVVM ViewModelプロパティのバッキングフィールド

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

「プロパティまたはインデクサーはアウトまたはREFパラメータとして渡すことはできません」。

どうすればよいですか?

答えて

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のロジックを実装する必要があります。しかし、読みやすさを望むなら、これは一つの方法です。 –

関連する問題