2016-03-10 28 views
8

RelayCommandの非常に一般的な実装は、以下の行を含めるようだ:RelayCommandの一般的な実装はMVVMパターンに違反していますか?

public event EventHandler CanExecuteChanged 
{ 
    add 
    { 
     CommandManager.RequerySuggested += value; 
    } 
    remove 
    { 
     CommandManager.RequerySuggested -= value; 
    } 
} 

CommandManagerは、WPFのコンポーネントであり、通常は私のコマンドはのviewmodelクラスに位置しているので、これは、私にとって非常に欠陥があると思われます。ビューモデルはビューを知っていると想定されていないので、異なるフレームワークなどで動作するはずです。これは私にとって非常に奇妙なようです。たとえば、WPF名前空間(たとえばPCL)を知らない余分なプロジェクトでビューモデルを分割すると、この実装は不可能です。

この実装はMVVMパターンに違反していますか?
またはRelayCommandをあなたのビューにどういう形で置いていますか?
これに実際に欠陥がある場合は、この問題を解決するベストプラクティス実装がありますか?

+0

あなたのviewmodelは参照用ではありません。だからOK。 – blindmeis

+0

@blindmeisビューコンポーネントを使用することによって、ビューコンポーネントが参照されます。これは、非wpfアプリケーションでこのRelayCommand実装を使用しようとするとかなり明確になります。 –

+0

私はあなたが別の非wpfアプリケーションでwpfのviemodelを使用すると思いません:)主な目的はUIなしのテストであり、動作します。 – blindmeis

答えて

3

これは、チュートリアルを特定のMVVMフレームワークに結びつけるのではなく、一般的な自分自身のMVVMチュートリアルとして機能するチュートリアルのケースでのみ使用される、簡単で迅速な&ダーティーな実装です。

このアプローチ - 密結合以外は - 他のいくつかの欠点があります。

CommandManager.InvalidateRequerySuggested()メソッドが呼び出されると、すべてのコマンドのCanExecuteメソッドが呼び出されます。アプリケーションに100sのコマンドがある場合、これはWPFアプリケーションのパフォーマンスに深刻な影響を与える可能性があります。

私は個人的には常に成熟MVVMフレームワークを使用することをお勧め(PrismはLOBアプリケーションのための私のお気に入りです)。そこのコマンドは、通常、このようにそれを実装していませんが、1つのコマンドのCanExecute検証をトリガする(プリズムの場合)MyCommand.OnCanExecuteChanged()を呼び出します。

お互いに依存する複合コマンドまたは複数のコマンドがある場合は、コード内で自分自身を結び付けます。つまり、使用されているビュー内に関連コマンドのリストを格納してループスルーまたはマルチキャスト委任して代わりにそれを呼び出す。

はMVVMパターン違反この実装ですか?技術的にはい

また、RelayCommandを何らかの形で配置することはできますか?あなたは外部の工場でそれを抽象化することができるかもしれないけれども

本当に、それが意味をなすように思わないでくださいしない(上記の問題を参照)

これは確かに欠陥がある場合は、そこにありますこの問題を解決するベストプラクティスの実装ですか?

とにかくコマンドの状態をグローバルに無効にしないでください。自分の実行状態を結びつける必要があるコマンドを自分で結びます。

関連する問題