Question

三輪の牛 on Sun, 16 Feb 2014 12:25:02


MVVMについてお教えください。

私は現在のところ Windows Forms を使って開発しています。

今すぐMVVMを使用する予定はありませんが、MVVM採用の際の参考にしたいと思います。

1)MVVMではViewModelがデータバインディングの対象になると理解しています。

DataGridの各行もViewModelをバインディングするのでしょうか。それともModelですか。

2)ViewModelはModelが持つプロパティを再実装し、バインディング対象にすると理解しています。

PropertyDescriptorを作成し、ViewModelにあるプロパティはViewModelのプロパティを

ViewModelにないプロパティはModelのプロパティを直接アクセスする方法、

デザインパターンで言うところのChain of Responsibility的な発想で、PropertyDescriptorを作成しておけば

カスタマイズしたいプロパティだけをViewModelに記述する方法ができそうな気がしています。

この方法または類似の方法を採用されている例や予測される問題などがありましたらお教えください。


http://systemartlaboratory.com/



Sponsored



Replies

trapemiya on Mon, 17 Feb 2014 02:47:17


MVVMは概念であり、View、ViewModel、Modelの相当するクラスが1つずつあるわけではなく、それぞれをどのようなクラス群で構成するかに決まりはありません。よって、

>1)MVVMではViewModelがデータバインディングの対象になると理解しています。

>DataGridの各行もViewModelをバインディングするのでしょうか。それともModelですか。

も、ViewModelやModelをどのようなクラス群で構成するかによって変わると思いますので、なかなか答えづらい質問だと思います。ただ、私は、この場合は以下のように構築すると思います。
プロパティのみ実装されているModelから、INotifyPropertyChangedを実装したUIオブジェクトのObservableCollecionを作成し、それをViewModelで提供し、DataGridにはこのObservableCollecionをバインドさせます。よって、ViewModelオブジェクトは1つしかありません。

2)についてはあまりそのような例を見たことがなく、私も経験が無くて自信がないのですが、WPFはバインディングでPropertyDescriptorを使用しており、その辺りがややこしくなるかもしれません。

(参考)
PropertyDescriptor and WPF Binding mechinsm
http://stackoverflow.com/questions/19784028/propertydescriptor-and-wpf-binding-mechinsm

ひらぽん on Mon, 17 Feb 2014 05:05:18


私も DataGrid(サードパーティ製のですが)を多用してますが、trapemiya さんと同じくModel に各行(レコード)とバインディングするクラスを用意し、ViewModel には ObservableCollection のプロパティを用意し View とバインドさせています。

たとえば私が現在携わっているプロジェクトの場合、顧客クラス(Customer) を Model に用意。ViewModel には Customer のコレクション(ObservableCollection<Customer>) を変更通知プロパティとして用意し、顧客一覧画面のデータグリッドの DataSource プロパティにバインドさせてます。


Customer はプロジェクト内で汎用的に使われているクラスで、データグリッド等での編集も想定して INotifyPropertyChanged インターフェイスを実装してます。Customer は INotifyPropertyChanged を実装してるといえども ViewModel でなくModelとして扱っています。

以上、何かの参考になれば幸いです。

三輪の牛 on Mon, 17 Feb 2014 14:31:25


trapemiyaさん、ひらぽんさんありがとうございます。

MVVMはプロパティを再実装するものと誤解していたようです。

お教えいただいたことで、Chain of Responsibility的な発想でPropertyDescriptorを作る必要もないと思いました。

またエンティティはModelに、エンティティのリストはViewModelに持たせると理解しました。

追加で質問させてください。

ひらぽんさんの例に挙げてくださった、顧客クラスの様なルートエンティティについてはわかりました。

伝票-伝票明細のようなサブエンティティをもつ場合はどのようになさっていますか。

MVVMではないのですが、私は伝票のプロパティとしてIBindingListを実装した伝票明細のリストを持たせています。

ですのでViewではBindingList<伝票>のネストされたプロパティとしてBindingList<伝票明細>をバインディングさせています。

trapemiya on Tue, 18 Feb 2014 09:19:07


伝票(マスター)部分は通常のWindowで作り、明細部分はUserControlで作成し、WindowにUserControlを配置して、マスター/明細の画面を実現しています。
マスター、明細共に、ViewとViewModelのオブジェクトが1つずつ存在しています。

三輪の牛 on Wed, 19 Feb 2014 15:06:17


trapemiyaさんありがとうございます。

サブエンティティを持つ場合にも、エンティティはModelに、エンティティのリストはViewModelに持たせると理解しました。

MVVM採用の際には参考にさせていただきます。

現在の認識としては、伝票-伝票明細の様な関係ですと明細合計金額の計算などModel内での結びつきが強く、

サブエンティティのリストがModelから分離するデメリットと、

MVVMのメリット(まだ理解していないですが)とのトレードオフになるのかなと思っています。

trapemiya on Thu, 20 Feb 2014 00:43:32


現在の認識としては、伝票-伝票明細の様な関係ですと明細合計金額の計算などModel内での結びつきが強く、

いえ、特にModel内での結びつきは強くないと思いますよ。明細の合計金額などModelから導かられるものは、明細のViewModelが如何ようにも料理して、それをプロパティとして公開するべきなんだろうと思います。そして、それを伝票のViewにおける明細合計金額を表示するTextBlockにバインドすれば済みます。よって、伝票のViewは、伝票のViewModel、および明細のViewModelとバインドすることになります。実際には伝票のViewは伝票のViewModelとのみバインドしますが、伝票のViewModelが明細のViewModelの参照を保持して、それをプロパティとして公開しますので、このプロパティを通して結果的に明細のViewModelとバインドすることが可能になります。

ひらぽん on Thu, 20 Feb 2014 02:23:45


サブエンティティを持つ場合にも、エンティティはModelに、エンティティのリストはViewModelに持たせると理解しました。

私はそういう認識はないです。仮に持たせるとしても Model (例えば Order クラス) のプロパティに ObservableCollection<伝票明細> のコレクションを保持し View に直接バインド、もしくは UserControl を介して公開という形になるかと思います。もし ObservableCollection<伝票明細> のUIをよりリッチにしたいなら、途中に ViewModel を設けるか否かという感じですかね。

#うまく伝わるか不安ですが・・・

三輪の牛 on Thu, 20 Feb 2014 12:26:26


trapemiyaさん、ありがとうございます。
 済みません。伝票-伝票明細の結びつきの件、一般性があるような書き方をしてしまいました。
 当方の設計では伝票-伝票明細の結びつきが強くなっています。 例に挙げた明細合計金額計算はModel内で完結しており、単にバインディングすれば逐次計算結果が表示されるようにしています。
 ひらぽんさんありがとうございます。
>仮に持たせるとしても Model (例えば Order クラス) のプロパティに
>ObservableCollection<伝票明細> のコレクションを保持し
 今はそうしています。伝票のプロパティにBindingList<伝票明細>を持っています。INotifyPropertyChangedおよびBindingList.ListChangedによって合計金額の計算を実行しています。ひらぽんさんの方法であればModelのバインディングに関しては今と同じ方法なのでMVVMへの移行も何とかなりそうな気がしてきました。
>UIをよりリッチにしたいなら、途中に ViewModel を設けるか否かという感じ
 このあたりの感覚も参考にさせていただきます。