18

私はしばらくこれに戸惑っていました。私はRibbonWindowMVVMパターンを使用してかなり大きなWPFアプリケーションを書いています。画面RibbonBarの上部にはメニューがあり、残りの部分にはさまざまなビューが表示されます。一部のビューには他のビューが含まれ、一部のビューには子Windowsを起動するボタンがあります。

これまで、ファイルの背後にあるコードの表示からこれを行ってきましたが、MVVMを使用する場合、これらのファイルは空であると想定されていることを認識しています。子ウィンドウの起動コードをViewModelに移動することはできますが、メインへの参照RibbonWindow(子ウィンドウの所有者として設定するため)が必要になり、それは正しくないようです。

MVVMを使用してこれを通常どのように達成するかについてのアドバイスやヒントをいただければ幸いです。

4

6 に答える 6

20

私は通常、ある種のWindowViewLoaderServiceを作成することによってこれを処理します。プログラムが初期化されたら、ウィンドウとViewModelを次のようなコードで登録します。

WindowViewLoaderService.Register(TypeOf(MainWindowView), TypeOf(MainWindowViewModel));
WindowViewLoaderService.Register(TypeOf(MyWindowView), TypeOf(MyWindowViewModel));

次に、たとえばViewModelからこのサービスを呼び出すことができ、参照する必要があるのは他のViewModelだけです。たとえば、MainWindowViewModelを使用している場合、次のようなコードが含まれている可能性があります。

var myChildWindowVM = new MyWindowViewModel();
WindowViewLoaderService.ShowWindow(myChildWindowVM);

次に、WindowViewLoaderServiceは、渡された指定されたViewModelに関連付けられているビューを検索します。そのビューを作成し、そのDataContextを渡したViewModelに設定してから、ビューを表示します。

このようにして、ViewModelはビューについて知ることはありません。

あなたはこれらのサービスのあなた自身のものをかなり簡単に転がすことができます。必要なのは、キーがViewModelTypeで、値がViewTypeであるディクショナリを保持することだけです。Registerメソッドはディクショナリに追加され、ShowWindowメソッドは渡されたViewModelに基づいて正しいビューを検索し、ビューを作成し、DataContextを設定してから、Showを呼び出します。

ほとんどのMVVMフレームワークは、箱から出してすぐにこのようなものを提供します。たとえば、Caliburnには、このフレームワークでViewLocatorと呼ばれる命名規則を使用する洗練されたものがあります。要約するリンクは次のとおりです。http://devlicio.us/blogs/rob_eisenberg/archive/2010/07/04/mvvm-study-segue-introducing-caliburn-micro.aspx

一方、CinchはそれをWPFUIVisualizerServiceと呼んでおり、ここで実際の動作を確認できます:http: //www.codeproject.com/KB/WPF/CinchIII.aspx

これらはあなたが転がるのを助けるはずです。

于 2011-05-06T21:12:30.090 に答える
6

さて、最初の注意点の1つは、「コードビハインドにコードがまったくない」というのは、実際には「神話」であるということです。実用的でありたいと思っていて、コードがあれば(できるだけ少ないほうがよい)、生活が楽になり、問題が解決することがわかった場合は、それを使用する必要があります。

ただし、この状況では、実際にはこれを行うためのいくつかの緩く結合された方法があります。あなたはあなたのために相互作用をするサービスを持つことができます。ViewModelからユーザーとの対話を開始すると、サービスがそれを処理し(たとえば、ChildWindowを表示することにより)、ユーザーの応答を返します。そのサービスは、簡単にテストするためにモックすることができます。そして、それは別々にテストすることができます。

つまり、自分で物事をやりたい場合です。フレームワークに手間のかかる作業を行わせたい場合は、PrismInteractionRequestが提供する機能を確認できます。これは、ユーザーインタラクションパターンに関するセクションを含む、高度なMVVMシナリオについて説明しているMSDNの記事です。それが私のやり方で、とてもシンプルでエレガント、そして簡単です。

お役に立てれば :)

于 2011-05-06T21:36:31.220 に答える
3

Mattの答えをさらに一歩進めるために、すべてのビューをユーザーコントロールにすることができます。次に、ViewContainerを作成します。これは、データテンプレートを含むウィンドウです(説明したとおり)。

次に、開きたいビューモデルをウィンドウサービスに送信します。ウィンドウサービスはDataContextを設定します。次に、サービスがウィンドウを開き、contentcontrolがビューモデルの正しいビューを解決します。

これは、すべての登録がXAMLで行われ、ウィンドウサービスがその方法を知っていることを意味します...ウィンドウを開いたり閉じたりします。

于 2011-05-07T12:46:02.133 に答える
1

これは古い投稿ですが、おそらくこれは途中で誰かを助けるでしょう:私はMVVMを使用し、ViewModelからViewに戻る子ウィンドウを開くためのイベントを発生させます。背後にある唯一のコードは、イベントの処理、ウィンドウのオープン、子ウィンドウの所有者の設定であり、これでほぼ完了です。ビューモデルでは、eventhandlerがnullの場合、ビューによってサブスクライブされてお​​らず、起動しません。VMはビューを認識していません。コードも非常にシンプルで、数行しかかかりません。

于 2016-11-13T13:03:11.160 に答える
0

この状況では、Viewは子ウィンドウのオープンを処理する必要があります。ただし、ViewModelはウィンドウの作成を促進する可能性がありますが、Viewを呼び出して新しいウィンドウを作成します。これにより、MVVMパターンのロジックが保存されます。ViewModelには「頭脳」がありますが、特定のウィンドウの作成には関与しません。

于 2011-05-06T21:01:27.533 に答える
0

ViewModelは、システム状態とUIロジックを表示するためにのみ使用されます。1つのビューモデルが複数のビューによって参照される場合があります。親子関係、位置、レイアウト、サイズなどのUI固有のコードについての知識はありません。したがって、ViewModelの状態変更イベントまたはコマンドイベントとイベント引数の背後にあるビューのコードで子ウィンドウをポップすることをお勧めします。このようにして、UIレイヤーの親ビューを指定できます。

于 2017-05-25T07:52:34.157 に答える