2016-08-31 13 views
8

プロパティを複数のクラスに正しく渡す方法を理解しようとしています。私はちょうど各クラスにINotifyPropertyChangedを実装し、プロパティの変更を聞くことができることを知っていますが、これはかなりの不必要なコードのようです。プロパティの変更を複数のクラスに伝播する

状況:FilterStatement(文字列)とFilter(Filterクラス):
私は2つの依存関係プロパティで(のはClass1それを呼びましょう)クラスを持っています。文の設定はフィルタに影響を及ぼし、逆も同様です。
ただし、文とフィルタの間の変換ロジックはClass1ではなく、Class3にあります。Class1は直接わかりません。その間には、変更を通過するだけのClass2があります。 (実際の状況では完全には一致しませんが、クラス1〜3のViewModel、モデル、リポジトリを想像することができます)。

public class Class1 
{ 
    public static readonly DependencyProperty FilterProperty = DependencyProperty.Register(
     "Filter", 
     typeof(Filter), 
     typeof(Class1), 
     new FrameworkPropertyMetadata(null)); 

    public static readonly DependencyProperty FilterStatementProperty = DependencyProperty.Register(
     "FilterStatement", 
     typeof(String), 
     typeof(Class1), 
     new FrameworkPropertyMetadata(null)); 

    public Filter Filter 
    { 
     get { return (Filter)GetValue(FilterProperty); } 
     set { SetValue(FilterProperty, value); } 
    } 

    public string FilterStatement 
    { 
     get { return (string)GetValue(FilterStatementProperty); } 
     set { SetValue(FilterStatementProperty, value); } 
    } 

    public Class2 MyClass2Instance { get; set; } 
} 

public class Class2 
{ 
    public Class3 MyClass3Instance { get; set; } 

    public void ChangeClass3Instance(object someParam) { 
     ... // this can change the instance of MyClass3Instance and is called frome somewhere else 
     // when changed, the new Class3 instance has to get the property values of Class1 
    } 
} 

public class Class3 
{ 
    private Filter _filter; // here is where the filter set in Class 1 or determined by the statement set in class 1 has to be put 

    public string MyFilterToStatementConversionMemberFunction(Filter filter) 
    { 
     ... 
    } 

    public Filter MyStatementToFilterConversionMemberFunction(string statement) 
    { 
     ... 
    } 
} 

私の素朴な解決策は、すべての3つのクラス間での特性を複製Class2Class3INotifyPropertyChangedを実装し、Class3まで、バックClass1までの結果ですべてを伝播し、変化に耳を傾けることであろう。これには良い解決策はありませんか?

+0

MVVMライトのようなメッセンジャーを使用できませんか?お互いを知る必要のないVM間でプロパティの変更を通知できるように設計されています。 – Keithin8a

+0

私は現在1つを使用していません。これを使うのは避けたいのですが、解決策になりそうです。 –

+1

なぜ私は私がコメントを投稿すると思ったのですか?答え。あなたが正しいことをやっていないという道を歩いている可能性があるように見えるのは、より良い方法があると思うからです。しかし、あなたは自分のプロジェクトを私よりもよく知っているので、理由があると確信しています;ちょっと注意してください;) – Keithin8a

答えて

3

実際には、Class1はコントロール(ViewModelである)ではありませんが、DependencyPropertyというプロパティを作成する理由はありません。INotifyPropertyChangedの実装で十分です。 はしかし、DependencyPropertyと実装は、同様に動作するはずです:

public class Class1 
{ 
    public static readonly DependencyProperty FilterProperty = 
     DependencyProperty.Register(
      nameof(Filter), 
      typeof(Filter), 
      typeof(Class1), 
      new PropertyMetadata(OnPropertyChanged)); 

    public static readonly DependencyProperty FilterStatementProperty = 
     DependencyProperty.Register(
      nameof(FilterStatement), 
      typeof(string), 
      typeof(Class1), 
      new PropertyMetadata(OnPropertyChanged)); 

    public Filter Filter 
    { 
     get { return (Filter)GetValue(FilterProperty); } 
     set { SetValue(FilterProperty, value); } 
    } 

    public string FilterStatement 
    { 
     get { return (string)GetValue(FilterStatementProperty); } 
     set { SetValue(FilterStatementProperty, value); } 
    } 

    public Class2 MyClass2Instance { get; set; } 

    private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     var c = (Class1)d; 
     if (c.MyClass2Instance?.MyClass3Instance != null) 
     { 
      if (e.Property == FilterProperty) 
      { 
       c.FilterStatement = c.MyClass2Instance.MyClass3Instance.MyFilterToStatementConversionMemberFunction((Filter)e.NewValue); 
      } 
      else if (e.Property == FilterStatementProperty) 
      { 
       c.Filter = c.MyClass2Instance.MyClass3Instance.MyStatementToFilterConversionMemberFunction((string)e.NewValue); 
      } 
     } 
    } 
} 

Filter.Equalsが適切に実施されるべきであるとClass3の変換方法は、同じ引数に同じ値を返す必要があり、注意してください。

+0

今、私はあなたが "直接"という意味を理解しています - 責任について考える必要がありますが、これはうまくいきます。私はその解決策を思いつくためにイベントに集中することでした –

0

あなたはこれをあまりにも複雑に思っています。観察可能なパターンは、ユーザーインターフェイスの実装に適しています。 にすべてのプロパティを設定するロジックをClass3でコーディングしてみませんか?私は、オーバーロードセッターFilterStatmentFilterClass1に入れました。これはViewModelも良い解決策です。より簡単な解決策として。

+0

'Class1'は' Class2'を知っていますが、 'Class2'は' Class3'を知っていますが、これは真実ではありません。私はClass3のプロパティをClass3から設定できません。責任は間違っているので、これを行う。 –

+0

私はあなたが簡単にコードを投稿すると思います。 – mati

+0

私はクラス構造の例を構築します。 –

関連する問題