9

MVVM アプリケーションがあります。ViewModel の 1 つは、ObservableCollection に値を設定する 'FindFilesCommand' です。次に、同じ ViewModel に「RemoveFilesCommand」を実装します。このコマンドは、さらにユーザー入力を取得するためのウィンドウを表示します。

MVVMパラダイムを維持しながらこれを行うための最良の方法はどこですか? どういうわけか:

newWhateverWindow( ).Show( )

ViewModel では間違っているようです。

乾杯、

スティーブ

4

7 に答える 7

1

Onyx(http://www.codeplex.com/wpfonyx)は、これに対してかなり優れたソリューションを提供します。例として、次のようにViewModelから使用できるICommonDialogProviderサービスを見てください。

ICommonFileDialogProvider provider = this.View.GetService<ICommonDialogProvider>();
IOpenFileDialog openDialog = provider.CreateOpenFileDialog();
// configure the IOpenFileDialog here... removed for brevity
openDialog.ShowDialog();

これは、具体的なOpenFileDialogの使用と非常に似ていますが、完全にテスト可能です。本当に必要なデカップリングの量は、実装の詳細になります。たとえば、あなたの場合、ダイアログを使用しているという事実を完全に隠すサービスが必要な場合があります。次のようなもの:

public interface IRemoveFiles
{
   string[] GetFilesToRemove();
}

IRemoveFiles removeFiles = this.View.GetService<IRemoveFiles>();
string[] files = removeFiles.GetFilesToRemove();

次に、ビューにIRemoveFilesサービスの実装があることを確認する必要があります。このサービスには、いくつかのオプションがあります。

Onyxはまだリリースの準備ができていませんが、コードは完全に機能しており、少なくとも参照ポイントとして使用できます。私はV1インターフェースをすぐにリリース安定化することを望んでおり、まともなドキュメントとサンプルができ次第リリースする予定です。

于 2009-03-19T19:54:48.647 に答える
1

ハイメ・ロドリゲスとカール・シフレットのサウスリッジ不動産の例では、ビューモデル、より具体的には、バインドされたコマンドの実行部分でウィンドウを作成しています。

    protected void OnShowDetails ( object param ) 
    {
        // DetailsWindow window = new DetailsWindow();
        ListingDetailsWindow window = new ListingDetailsWindow();
        window.DataContext = new ListingDetailsViewModel ( param as Listing, this.CurrentProfile ) ; 
        ViewManager.Current.ShowWindow(window, true); 
    } 

リンクは次のとおりです。 http://blogs.msdn.com/jaimer/archive/2009/02/10/mv-vm-training-day-sample-application-and-decks.aspx

それは大きな問題ではないと思います。結局のところ、ビューモデルはビューとビジネス層/データ層の間の「接着剤」として機能するため、ビュー (UI) に結合されるのは普通のことです...

于 2009-03-18T07:45:41.647 に答える
0

私は言わなければならないでしょう、サービスはここに行く方法です。

サービスインターフェイスは、データを返す方法を提供します。次に、そのサービスの実際の実装では、インターフェイスで必要な情報を取得するためのダイアログなどを表示できます。

これをテストする方法では、テストでサービスインターフェイスをモックすることができ、ViewModelは賢明ではありません。ViewModelに関する限り、サービスに情報を要求し、必要な情報を受け取りました。

于 2009-03-18T04:31:08.120 に答える
0

私たちがやっていることは、ここで説明されているようなものです: http://www.codeproject.com/KB/WPF/DialogBehavior.aspx?msg=3439968#xx3439968xx

ViewModel には、ConfirmDeletionViewModel というプロパティがあります。プロパティを設定するとすぐに、動作がダイアログを開き (モーダルかどうかに関係なく)、ConfirmDeletionViewModel を使用します。さらに、ユーザーがダイアログを閉じたいときに実行されるデリゲートを渡しています。これは基本的に、ConfirmDeletionViewModel プロパティを null に設定するデリゲートです。

于 2010-07-19T08:41:56.753 に答える
0

MVVMでもこの問題に遭遇しました。私の最初の考えは、ダイアログを使用しない方法を見つけようとすることです。WPF を使用すると、ダイアログを使用するよりも、よりスマートな方法を考え出すのがはるかに簡単になります。

それが不可能な場合、ViewModel で Shared クラスを呼び出してユーザーから情報を取得するのが最善の方法のようです。ViewModel は、ダイアログが表示されていることをまったく認識しない必要があります。

したがって、単純な例として、ユーザーが削除を確認する必要がある場合、ViewModel は DialogHelper.ConfirmDeletion() を呼び出すことができます。これは、ユーザーが「はい」または「いいえ」と答えたかどうかのブール値を返します。ダイアログの実際の表示は、Helper クラスで行われます。

より高度なダイアログで大量のデータを返す場合、ヘルパー メソッドは、ダイアログからのすべての情報を含むオブジェクトを返す必要があります。

MVVM の残りの部分に最もスムーズに適合するわけではないことに同意しますが、より良い例をまだ見つけていません。

于 2009-03-18T04:00:19.800 に答える
-1

この種のダイアログの場合。FindFilesCommand のネストされたクラスとして定義します。多くのコマンド間で使用される基本的なダイアログの場合、それらのコマンドにアクセス可能なモジュールでそれを定義し、それに応じてコマンドにダイアログを構成させます。

コマンド オブジェクトは、ダイアログが残りのソフトウェアとどのように対話しているかを示すのに十分です。私自身のソフトウェアでは、Command オブジェクトは独自のライブラリに存在するため、ダイアログはシステムの残りの部分から隠されています。

私の意見では、手の込んだことをするのはやり過ぎです。さらに、多くの追加のインターフェイスと登録メソッドを作成することを含む、最高レベルに維持しようとすることがよくあります。少しの利益のための多くのコーディングです。

他のフレームワークと同様に、奴隷的な献身はあなたをいくつかの奇妙な路地に導きます。コードの悪臭を感じた場合は、他に使用できる手法がないか判断する必要があります。繰り返しになりますが、ダイアログは、それらを使用するコマンドの横にしっかりとバインドして定義する必要があります。そうすれば、5 年後にコードのそのセクションに戻って、そのコマンドが扱っているすべてのことを確認できます。

繰り返しますが、ダイアログが複数のコマンドに役立ついくつかの例では、それらすべてに共通のモジュールでダイアログを定義します。ただし、私のソフトウェアでは、おそらく 20 個のダイアログのうち 1 個がこのようなものです。主な例外は、ファイルを開く/保存するダイアログです。ダイアログが数十のコマンドで使用される場合、インターフェイスを定義し、そのインターフェイスを実装するフォームを作成し、そのフォームを登録するという完全なルートに進みます。

国際的な使用のためのローカリゼーションがアプリケーションにとって重要である場合は、すべてのフォームが 1 つのモジュールに含まれていないため、このスキームでそれを考慮する必要があります。

于 2009-03-17T20:06:48.877 に答える