47

MVVMを使用してビューモデルのビューを閉じる賢い方法に出くわした人はいますか?

たぶん、バインディングを使用してビュー(ウィンドウ)を閉じるように通知する方法はありますか?

どなたかご意見をいただければ幸いです。

基本的に、loginViewModelにバインドされたloginViewがあり、ビューモデルで(コマンドのバインドを使用して)ログインが成功したかどうかをテストし、成功した場合は基本的に新しいビュー(メインビュー)をロードしてそのデータコンテキストをアタッチします。 ..

しかし、loginViewが表示されたままなので、アンロードするように通知する必要があります。

私はまた、他の状況でこの種のことをする必要があると確信しているので、一般的な解決策を望んでいました

何か案は?

4

11 に答える 11

36

編集:より詳細な説明については、私のブログ投稿を参照してください。

それを実現する必要がある場合は、作成したIRequestCloseViewModelインターフェイスを使用します。

このインターフェースには、RequestCloseという1つのイベントのみが含まれています。このイベントは、関連付けられたビューを閉じたいときに、ViewModel(ViewModelBaseクラスを継承し、IRequestCloseViewModelを実装する)によって発生します。

私のアプリでは、すべてのWindowは抽象クラスApplicationWindowから継承します。この抽象クラスは、DataContextが変更されるたびに通知され、ハンドラーでDataContextがIRequestCloseViewModelをサポートしているかどうかを確認します。この場合、イベントが発生したときにウィンドウを閉じるようにイベントハンドラーが設定されます。

あるいは、ケントが言ったように、外部クラスでこのメカニズムを処理するスクリーンコントローラーを使用できます。

于 2009-09-28T11:04:53.320 に答える
23

使用しているMVVMフレームワークはわかりませんが、ほとんどの場合、送信されるメッセージを簡単に登録できる、ある種のメッセージング/通知ソリューションが含まれています。ビューが「CloseWindowsBoundTo」やviewModelなどのメッセージを送信者として登録できなかったと想像できる理由はありません。次に、ビューで、そのメッセージに登録し、現在のデータコンテキストを送信者と比較できます。それらが一致する場合は、ウィンドウを閉じます。

シンプルで、ビューモデルからビューを抽象化します。

MVVM-lightツールキットを使用した私のアプローチは次のとおりです。

ViewModelの場合:

public void notifyWindowToClose()
{
    Messenger.Default.Send<NotificationMessage>(
        new NotificationMessage(this, "CloseWindowsBoundToMe")
    );
}

そして、ビューで:

Messenger.Default.Register<NotificationMessage>(this, (nm) =>
{
    if (nm.Notification == "CloseWindowsBoundToMe")
    {
        if (nm.Sender == this.DataContext)
            this.Close();
    }
});
于 2010-07-20T19:36:55.447 に答える
9

以前はdialogcloserに接続された動作を使用していましたが、以下の解決策を使用すると簡単になります。以下のサンプルは、簡単にするためにウィンドウの閉じるボタンの例を示しています。

コマンドパラメータとしてウィンドウを渡します。

ビューのボタンxaml:

CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}"

ビューモデルのコマンドexecuteメソッドで:

if (parameter is System.Windows.Window)
{
    (parameter as System.Windows.Window).Close();
}
于 2014-02-27T03:37:47.310 に答える
8

通常、画面のアクティブ化/非アクティブ化を駆動するために、ある種のコントローラー/プレゼンター/サービスを使用します。MVVMは、それらすべてを支配する1つのパターンとなることを意図したものではありません。重要なアプリケーションでは、他のパターンと組み合わせる必要があります。

とは言うものの、状況によっては、子ビューモデルのライフサイクルを管理するビューモデルを用意することが理にかなっています。たとえば、EditorViewModel子ビューモデルのコレクションを管理するがあります(編集中のドキュメントごとに1つ)。その場合、このコレクションに追加/削除するだけで、ビューがアクティブ化/非アクティブ化される可能性があります。しかし、これはあなたのユースケースに合うようには聞こえません。

于 2009-09-27T20:19:52.620 に答える
7

http://adammills.wordpress.com/2009/07/01/window-close-from-xaml/

<Style.Triggers> <DataTrigger Binding="{Binding CloseSignal}" Value="true"> <Setter Property="Behaviours:WindowCloseBehaviour.Close" Value="true" /> </DataTrigger> </Style>

于 2010-07-19T16:13:10.520 に答える
4

ウィンドウにアタッチし、実行するとウィンドウを閉じるコマンドを作成できます。次に、そのコマンドをビューモデルのプロパティにバインドし、ウィンドウを閉じたいときにコマンドを実行できます。

于 2009-12-14T18:51:57.773 に答える
2

LoginViewModelをインスタンス化し、LoginViewを表示するApplicationControllerを使用します。ユーザーがログイン画面に進むと、ApplicationControllerはLoginViewを閉じ、MainViewとそのMainViewModelを表示します。

これを行う方法は、 WPFアプリケーションフレームワーク(WAF)プロジェクトのサンプルアプリケーションに示されています。

于 2009-10-02T17:54:24.337 に答える
2

この回答は、これを行う別の方法を示しています。

ViewModelはどのようにフォームを閉じる必要がありますか?

アタッチされたプロパティを使用して、DialogResultウィンドウプロパティをViewModelプロパティにバインドします。DialogResultの値をtrueまたはfalseに設定すると、ビューが閉じます。

于 2010-08-06T17:03:12.607 に答える
2

コードビハインドでEventHandlerを閉じて、コマンドバインディングを使用できるビューモデルの他のすべてを処理します。

于 2012-06-30T18:37:52.240 に答える
1

イベントを使用してこれを行うこともできます。ビューコードビハインドには3行のコードが必要ですが(一部のMVVM純粋主義者はこれを嫌います)。

ビューモデルで、ビューがサブスクライブできるイベントを作成します。

    public event CloseEventHandler Closing;
    public delegate void CloseEventHandler();
    private void RaiseClose()
    {
        if (Closing != null)
            Closing();
    }

で、次のように、initializecomponentメソッドの後にイベントをサブスクライブするビューを表示します。

        public View
        {
           *//The event can be put in an interface to avoid direct dependence of the view on the viewmodel. So below becomes
            //ICloseView model = (ICloseView)this.DataContext;*
            ProgressWindowViewModel model = (ProgressWindowViewModel)this.DataContext;
            model.Closing += Model_Closing;
        }
        private void Model_Closing()
        {
             this.Close();
        }

ViewModelからビューを閉じる準備ができたら、RaiseClose()を呼び出すだけです。

このメソッドを使用して、ビューモデルからビューにメッセージを送信することもできます。

ビューをビューモデルに直接依存させないように、イベントをインターフェイスに配置できます。

于 2017-08-11T11:38:38.727 に答える
0

viewmodelからビューを閉じるために、ここからダウンロードできるGalasoft MVVM LightToolkitを使用しました:http ://www.mvvmlight.net/

  1. 次のようなクラスを作成します。publicclassClosingRequested:MessageBase {}

  2. これをビューコンストラクターに追加します。Messenger.Default.Register(this、vm、msg => Close());

  3. これを呼び出してウィンドウを閉じます。Messenger.Default.Send(new ClosingRequested()、this);

于 2015-07-28T15:58:17.783 に答える