2009-05-29 15 views
3

私はwpf mvvmアプリケーションの作成を開始しました。 ViewModelに不可欠な要素と思われるのは、ビューがビューモデルとやりとりすることを可能にする疎結合の方法を持つ一連のICommandです。MVVM ICommandの代替

私の質問はこれです。私は直接メソッドにバインドできないのですか?

私はJosh SmithのICommandのRelayCommand実装を使用しています。これは、ICommandオブジェクトに差分値を挿入することを可能にしますが、実際には、ボタンのプッシュでviewmodelのメソッドを呼び出すことができる簡単な方法がありますか?私はMVVMに新たなんだ

は、私が(例えば)Buttonと、デリゲートを受け入れる性質を持っていないので、あなたは、メソッドに直接結合することはできませんいくつかの悟り

+1

メソッドにバインドすることができます:

答えて

7

が必要と考えています。代わりにICommandCommandプロパティがあります。 RelayCommand(別名DelegateCommand)は、代理人をラップするちょうどICommandです。

<Button Command="{ViewModelMethod SomeMethodName}"/> 

しかし、これは遅くなるだろうとなります

は、私は、ビューはマークアップ拡張機能を経由してビューモデル上の特定のメソッドにバインドすることは可能ではないでしょうなぜ技術的な理由を見ませんビューとビューモデルの結合を増やします。ビューがタイプ ICommandのビューモデル上のプロパティのみを知っている場合、そのコマンドの実装は、ビューが認識されずに完全に変更される(またはメソッドの名前が変更される)可能性があります。

+0

なぜそれは遅いでしょうか?反射を使用する必要がありますか?しかし、あなたが言及したカップリングの問題を理解しています。 – Jose

+0

実際、私はviewmodelコマンドへのバインディングも反射を使用するので、実際はずっと遅いとは思わない。ただし、このアプローチには欠点があります。そのViewModelCommandマークアップ拡張はバインディングではないため、ViewModelが変更されたときには更新されません:一度しか評価されません(DataContextChangedイベントにフックして再評価する必要はありません。 ..) –

+0

まず、私は「ゆっくり」ではなく「遅い」と言った。重要な違い。第二に、私はバインディング自体ではなく、呼び出されるメソッドの解決と呼び出しについて話していました。 VMによって作成されたデリゲートを使用する方が、ビューからメソッドを反映して解決するよりも迅速になります。だから、他のすべてのドローバックの上に、ビューからそれを行うことは遅くなるでしょう。 –

6

私は完全に同意しません。

コマンドの実行速度は関連性がありません。コマンドはユーザーの操作であり、スピードを必要としません。

カップリングについての引数にも欠陥があります。どのように{Binding MyProperty}が結合していないのですか?{ViewMethod MyMethod}はどうですか?

特別に細工された「コマンド」をメソッドにラップする要件は、愚かなものです。コマンドはカバーの下では便利な実装かもしれませんが、すでにC#でメソッドを持っていて、それを大きなものに置き換え、かさばるものは正しくありません。

MarkupExtensionとBindingについては、実際には難しいです。しかし、それを行うことができます。実際には、CodePlexのMethodCallプロジェクトを見ることができます: http://methodcallthing.codeplex.com/

バインドを使用してメソッドに「this」を選択し、バインディングを使用して引数をフェッチできます。そしてそれらはすべて生存している、すなわちコマンドが呼び出された時点で計算されている。別の特典機能は、メソッド呼び出しの結果をプッシュアウトすることです。バインディングを使用することもできます(OneWayToSource)。

+1

+1ケント・ブーガートアートの答えの欠陥を修正するため。あなたのソリューションは興味深いですが、ICommandがExecuteとCanExecuteの実装を組み合わせる良い方法であることは認識していません。 – HappyNomad

5

ICommandは、コントロールを有効にするために必要なCanExecuteを提供します。単純なデリゲートはそうではありません。 ICommandは道のりです。

3

マイクロソフトでは、ほとんどのアプリケーションでCanExecuteが必要であると感じたため、おそらくMicrosoftがコマンドをファーストクラスにする必要があったようです。私は、CanExecuteはあなたのビューモデルのプロパティにバインドする別のDependencyPropertyであったはずだと思っていますが、ちょっと、私は何を知っていますか?

おそらく彼らはまた、コントロールのデータインターフェイスからコマンドの実装を切り離す必要があると考えました。それでも、OOの根本的な原則であるように、ロジックが操作されているデータの近くに生きなければならないので、これは私にとって不必要なことです。

個人的には、MVVMでコマンドを使用するのは、それらを実装するために作成しなければならない混乱のためです。私はビューのコードビハインドのデリゲートイベントをビューモデルに任せるだけです。

+0

+1は、ビューモデル上のICommandsがコードビハインド内に小さな「間に」ロジックを持つよりも多くのコード/複雑です。それでも、このアプローチには、ビューモデルで持つのがよい論理的なExecute/CanExcuteペアリングが欠けています。 – HappyNomad