5

caliburn で MVVM の小さなデモ アプリケーションを作成しています。

MessageBoxここで、MVVM の方法を示したいと思います。

ShellViewダイアログの場合、 (ルート ビュー) で処理されWindowManager.ShowDialog、DialogsViewModelタイプで呼び出すだけのイベントを作成しました。私にとってはMVVMに固執しているようです。

しかし、メッセージボックスを表示してその結果を取得する方法は何ですか (OK またはキャンセル)?

私はすでにこの質問を見ましたが、答えも含まれていません。

アイゼンバーグ氏自身が次のように答えています。

「Caliburn には、カスタム メッセージ ボックスを呼び出すためのサービスが組み込まれています。」

彼がそれで何を意味するのか誰にもわかりますか?サンプルには見えません。

4

3 に答える 3

7

おっしゃるとおり、ビューモデル(例ConfirmationBoxViewModel)と適切なビューを用意するだけです。2 つのアクションを作成する必要があります (ビュー モデルを から継承した後Screen、 を使用する必要があります。代わりにTryCloseいつでも実装できますが、それはより多くの作業になります)。IScreen

public void OK()
{
    TryClose(true);
}

public void Cancel()
{
    TryClose(false);
} 

次に、他のビューモデルで:

var box = new ConfirmationBoxViewModel()
var result = WindowManager.ShowDialog(box);
if(result == true)
{
// OK was clicked
}

ダイアログを閉じた後、ダイアログから追加のデータを取得する必要がある場合は、ビュー モデルのプロパティにアクセスできることに注意してください (例: 選択したアイテム、表示名など)。

于 2013-07-07T09:40:14.290 に答える
0

ルート/メイン/シェル ビュー モデルが一種のDialogServiceインターフェイスを実装する場合、ダイアログを表示する必要がある他のすべてのビュー モデルは、ルート ビューモデルに依存することになります。場合によっては、これが望ましくない場合があります。たとえば、依存ループが発生する可能性がある場合などです:
DialogService (別名RootViewModel ) -> SomeViewModel - > RootViewModel

この依存関係の連鎖を断ち切る (そして実際に逆にする) ためのより複雑なアプローチは次のとおりです。

  • イベントを検出する動作を実装し、それをメイン ビューコンポーネントWindow.OnSourceInitializedにアタッチします。Windowこれは、ウィンドウ ハンドルが使用可能になったときに発生するイベントです。イベントが発生すると、動作は添付プロパティを介して渡されたハンドラーに通知します。
<my:WindowSourceBehavior InitListener="{Binding WindowListener}" />
public class WindowSourceBehavior : Behavior<Window>
{
  // ...
  // boilerplate code for IWindowListener InitListener dependency property
  // ...

  attachedWindow.SourceInitialized += (sender, evt) =>
  {
     // ...
     InitListener.SourceInitialized(sender as Window);
  }
}
  • DialogServiceは、動作の要求に応じてハンドラー (またはインターフェイス) を公開します。
public class DialogService : IWindowListener
{
  // ...
  public void SourceInitialized(Window rootWindow) { /* ... */ }
}
  • ルート ビュー モデルでは、(間接的に)依存関係として挿入されたDialogServiceを取得します。構築中に、ビューモデルにバインドされWindowListenerたプロパティ をDialogServiceハンドラ/インターフェースに設定します。
public MainViewModel(IWindowListener dialogServiceInDisguise)
{
  WindowListener = dialogServiceInDisguise;
}

public IWindowListener WindowListener { get; private set; }

そうすることで、DialogService はルート Window を取得することができ、ダイアログを表示する必要があるビューモデルは、メイン ビューモデルへの (n 間接的な) 依存関係を作成しません。

于 2015-03-30T19:30:54.777 に答える