2

Conductor ViewModelによってレンダリングされたCaliburn.Microシェル (つまり、他のビューを含む空のXAMLビュー) があります。そこから、次の方法で画面を開きます。

ActivateItem(...)

通常、ユーザーは新しく表示されたダイアログからいくつかの操作を実行し、ボタン ( OKCancelBuild ....) をクリックすると、(シェル内で)別の画面に遷移します。

public MyDialog : Screen
{
    public void Ok()
    {
        // TODO: Somehow tell the conductor or called of this class about this action.
    }
}

この種のダイアログ アクション/メッセージ画面遷移を実現するための良い方法は何ですか?

  • 単純な.NET イベントが可能です -- それは悪い考えではないでしょうか?
  • IEventAggregator見方を変えることでCMも動くはず
  • ViewModel の結果が閉じられた後、Shell Conductor からその結果を確認するTryClose()-- 可能であるはずですが、CM でこれを達成する方法がわかりません。
  • その画面からシェルコンダクタ インスタンスを参照します (IoC 経由または直接) - これは強い結合のようです。

アドバイスをお願いします。

4

1 に答える 1

3

私が推奨するアプローチは、EventAggregator を使用して VM 間のメッセージングを容易にすることです。

これは、特定の種類のイベントをリッスンしている複数のウィンドウがある場合 (たとえば、状況依存のプロパティを表示する可能性のある複数のツール ウィンドウを備えた Visual Studio スタイル インターフェイス) がある場合に特にうまく機能しますが、この実装では少しやり過ぎに思えます。もちろん、VM 間の良好な疎結合とイベントの欠如 (これは良いことです!) は依然として利点です。

モーダル ダイアログをポップアップしてオプションを提示し、最初の画面が返されたら別の画面をアクティブにしたいようです。

Deactivated項目が非アクティブ化されたときに発生する子 VMのイベントにイベント ハンドラーをアタッチできます。非アクティブ化されたアイテムが閉じられたかどうかを通知するために、引数にブール値も渡します。これを確認して、コンダクターで対応する画面をアクティブ化できます。

例えば

this.Deactivated += new EventHandler<DeactivationEventArgs>(WorkspaceViewModel_Deactivated);

void WorkspaceViewModel_Deactivated(object sender, DeactivationEventArgs e)
{
    if(e.WasClosed) // raise some event
}

次に、イベントをコンダクターに渡します。私は実際には、このイベント ルートには行きません。これは VM を一方向に結合するため、最も柔軟なソリューションではない可能性があります

別の方法として、イベント アグリゲーターを介してメッセージを送信し、子 VM が閉じたときに別のウィンドウを開く必要があることをコンダクターに通知します。同じ方法を使用できますが、分離されています

this.Deactivated += new EventHandler<DeactivationEventArgs>(WorkspaceViewModel_Deactivated);

void WorkspaceViewModel_Deactivated(object sender, DeactivationEventArgs e)
{
    if(e.WasClosed) MainConductor.EventAggregator.Publish(new ActivateWindowMessage(typeof(SomeVM));
}
于 2012-11-28T18:18:41.577 に答える