2012-03-10 4 views
0

私のWPFアプリケーションでは、ViewModelLocatorをIoCなしで使用しています。 MVVM-Lightフレームワークが提供する静的なViewModelLocator.Cleanup()メソッドを、自分のボタンから「クローズウィンドウコマンド」に結びつけて呼び出しています。このコマンドは、MainWindowViewModelインスタンスでインスタンスCleanup()メソッドを呼び出すstatic ViewModelLocator.Cleanup()を呼び出します。次に、インスタンスCleanup()メソッドは、MainWindowがバインドするプロパティー(DataContext)をnullに設定します。プロパティ上のセッターはPropertyChangedイベントを発生させます。不思議なことに、このプロパティをnullに設定してもウィンドウが閉じることはありません。MVVMを使用しているときにアプリケーションを終了するか、コントロールを閉じる

私はなぜこれが当てはまるのか理解しようとしていますか? MainWindowのDataContextをnullに設定した場合、それはWindow.Close()と同じではないでしょうか?私の場合、ウィンドウとそのすべての要素は画面上に残ります。しかし、それ以上のアクションを試みるとnullポインタ例外が発生し、DataContextバインディングプロパティが実際にnullに設定されていることを示します。これはデバッガでも確認されています。

私は、自分自身の「ウィンドウを閉じる」ボタンを作成するために、Application.Exitイベントをフックし、Window.Close()を発行することで回避策を作成しました(つまり、 /コマンドは、ウィンドウの右上にあるXボタンをクリックします)。 MVVMからUI要素(つまりWindowインスタンス)を直接呼び出すのはMVVMには適していないので、回避MVVMを使いやすいようにWindow.Close()機能を実装するためにViewServiceを使用しました。私はViewServiceイディオム(またはパターン)の大きなファンですが、ここでは必要ではないと思っています。ただし、アプリケーションを終了すると、アプリケーションのライフサイクルと結びつくべき特別なケースであることがわかりました.Netは、Window.Close()メソッドを発行してWPFアプリケーションを終了することしかできないようです。

感謝しています。

+0

私はあなたの質問が何であるか知らないが、nullにそののDataContextを設定することで、ウィンドウを閉じると – flq

+0

@flqかなり直感的で非常に有用ではないに聞こえる:あなたは、ユーザーコントロールのように、他の視覚的要素を「閉じる」ことに同意しますか、定期的に行われていますDataContextをViewModelにバインドするプロパティをnullに設定すると、私はウィンドウを閉じたり、アプリケーションを終了するために同じアプローチを取っていた。 ViewModelからアプリケーションを終了する正しい方法(それによってMVVMに優しい)のように思えました。もちろん、Propをnullに設定することは、適切かもしれないすべてのクリーンアップに従います。私はあなた自身の終了ボタンを実装したい場合、私の質問は、単純に、どのようにmvvmライトアプリを終了すると思いますか? – Bill

+0

ビューを閉じるこの方法は、MVVMのライト固有の動作ですか? – flq

答えて

1

私は元の質問に対する答えを見つけたと思います。

最初に、元の質問に対する答えは、ウィンドウを閉じるための適切な方法は、私が記述した "回避策"の行に沿っていることです。アプリケーションを閉じることは、それを行う方法のビットを持つウィンドウコントロールであるため、ビューから開始されたプロセスです。もちろん、ViewModelsでクリーンアップを実行したり、データを保存するようにユーザーに促したりするために、Application.Exitイベントをフックできます。

flqとの面白い議論の後、 ViewおよびViewModelリソースを解放するために、コントロールのDataContext(つまり、ViewModel)をnullに設定するだけで、どうすればいいですか?

ニュアンスのある興味深い議論はhereですが、基本的な答えは、親コントロールを見つけて、子リストから閉じるコントロールを削除することです。これは、VisibilityプロパティをCollapsedに設定してコントロールを表示させないこととは異なる目標を持つ別のテクニックです。次の例では、「これは」(すなわち、「クローズ」)を削除するためのコントロールです:

Panel p = (Panel) this.Parent; 
p.Children.Remove(this); 

私はあなたがまだそれから(すなわち、「この」)子を設定する必要がある場合はわからないにそのリソースを再申請する場合はnull、またはビジュアルツリーからそれを削除するだけの場合は、WPFがリソースを再請求する原因になります。上記のリンクされた議論は言及していない。元のdiscussionで述べたように、上記のテクニックは、特定のイベントにフックするか、他のアプリケーション固有のロジックを使用することで補うことができます。

関連する問題