locked
MVVMにおけるプロパティ値連動 RRS feed

  • 質問

  • こんにちは

    今回質問したいのは、Silverlightの画面用にMVVMを作成し、最下層のModel内プロパティ値が変更になったときに、プロパティ変更通知を最上位のViewModelを介して、別な階層のModelで取得する方法です。

    【MVVM構成】
    VM1
    ├VM21
    │└ObservableCollection(Of VM31)
    └VM22
     └P1

    ※言葉で説明すると、VM1というViewModelのプロパティとしてVM21とVM22があり、VM21のプロパティとしてObservableCollectionで定義されたVM31がある状態。
    ※尚、すべてのクラスでINotifyPropertyChangedを継承してあります。

    【やりたいこと】
    VM31でプロパティ値が変更されたときに、VM22でそのプロパティ変更通知を感知し、VM22内の別なプロパティ値を変更したい。

    【環境】
    ・VisualStudio2010 Pro(開発言語:VB.NET)
    ・Silverlight4

    わかる方がいましたらご教授をお願いたします。

    2012年3月28日 6:53

回答

  • ObservableCollectionの要素にイベントを定義というのは、PropertyChangedのイベントではなく、別途独自にイベントを定義するということでしょうか?

    そういうことになります。PropertyChangedはバインド先でリッスンしているのでバインド先への通知はPropertyChangedでいいんですが、今回はバインド先への通知ではないため、独自にイベントを定義する必要があります。

    WeakEventは最初はとっつきにくいですが、それほど複雑な概念ではありませんので、じっくりと腰を据えて理解されると良いと思います。メモリーリークに関しては、「MVVM model メモリーリーク」などで検索されると、参考になるページがいろいろ見つかると思います。
    MVVMのフレームワークとしていくつか存在しますが、もしそれらを利用されているのでしたら、フレームワークの方で対応している可能性もあります。もし、このようなフレームワークを利用されておらず、独自にMVVMパターンで構築されているのでしたら、ObservableCollectionの要素一つ一つをループで回しながら、それらの要素に追加した独自のプロパティ変更イベントを、ViewModelでリッスンするように設定するだけです。これはさほど難しいコードではないでしょう。しかし、このままではメモリーリークする可能性があるので、これにWeakEventパターンを適用する形になります。


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    • 回答としてマーク sugarwing 2012年3月29日 6:45
    2012年3月29日 6:33
    モデレータ

すべての返信

  • ObservableCollectionの要素にイベントを定義し、VM1でそのイベントをリッスンするようにしてはいかがでしょうか? Modelにイベントを定義する場合はメモリーリークしやすいので注意して下さい。以下の記事を参考にされると良いでしょう。

    イベントリスナが先にお亡くなりになっています。あれ?残念ながらメモリリークです。あのね、WeakEventパターンを使うといいと思うんだ。WeakEventManagerから派生して、抽象的なWeakEventTriggeredManager<TSource, TEventArgs>クラスを作ってみよう。
    http://d.hatena.ne.jp/zecl/20090509/p1


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    2012年3月29日 1:40
    モデレータ
  • trapemiyaさん

    ご返信ありがとうございます。

    ObservableCollectionの要素にイベントを定義というのは、PropertyChangedのイベントではなく、別途独自にイベントを定義するということでしょうか?

    また、参考のWeakEventの記事ですが、正直言って???という感じです。
    (今回初めてWeakEventというものを知った次第です)
    MVVMにこのWeakEventをどのように(VBで)組み込んで実装すればいいのかが思い浮かびませんでした。
    (参考ページをVBで行っているページも見つけましたが、やはりMVVMでの使用方法がわかりませんでした)
    WeakEvent パターンを VB で学んでみる

    2012年3月29日 6:05
  • ObservableCollectionの要素にイベントを定義というのは、PropertyChangedのイベントではなく、別途独自にイベントを定義するということでしょうか?

    そういうことになります。PropertyChangedはバインド先でリッスンしているのでバインド先への通知はPropertyChangedでいいんですが、今回はバインド先への通知ではないため、独自にイベントを定義する必要があります。

    WeakEventは最初はとっつきにくいですが、それほど複雑な概念ではありませんので、じっくりと腰を据えて理解されると良いと思います。メモリーリークに関しては、「MVVM model メモリーリーク」などで検索されると、参考になるページがいろいろ見つかると思います。
    MVVMのフレームワークとしていくつか存在しますが、もしそれらを利用されているのでしたら、フレームワークの方で対応している可能性もあります。もし、このようなフレームワークを利用されておらず、独自にMVVMパターンで構築されているのでしたら、ObservableCollectionの要素一つ一つをループで回しながら、それらの要素に追加した独自のプロパティ変更イベントを、ViewModelでリッスンするように設定するだけです。これはさほど難しいコードではないでしょう。しかし、このままではメモリーリークする可能性があるので、これにWeakEventパターンを適用する形になります。


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    • 回答としてマーク sugarwing 2012年3月29日 6:45
    2012年3月29日 6:33
    モデレータ
  • 早速のご返信、ありがとうございます。

    今は時間がないため、腰を据えてというのは難しいですが、後でもう一度考えたいと思います。

    2012年3月29日 6:43