0

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

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

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

考えていただければ幸いです。

4

1 に答える 1

1

flq とのコメント ディスカッションで提起されたものに加えて、元の質問に対する答えを見つけたと思います。

まず、元の質問に対する答えは、ウィンドウを閉じる適切な方法は、説明した「回避策」で行ったことに沿っているということです。アプリを閉じるのは、View によって開始されるプロセスです。これは、それを行うためのビットを持つ Window コントロールであるためです。もちろん、Application.Exit イベントをフックして、ViewModel でクリーンアップを実行したり、ユーザーにデータを保存するように促したりできます。

flq との興味深い議論の後で私が提起した質問はDataContext、View および ViewModel リソースを解放するためにコントロール (ViewModel) を null に設定しない場合、どうすればよいですか?

いくつかのニュアンスを含む興味深い議論がここにありますが、基本的な答えは、親コントロールを見つけて、閉じたいコントロールをその子リストから削除することです。これは、Visibility プロパティを Collapsed に設定してコントロールを非表示にするという目的とは異なる手法であることに注意してください。次の例では、"this" が削除されるコントロールです (つまり、"Closed")。

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

子 (つまり、"this") を null に設定してそのリソースを再利用する必要があるのか​​、それともビジュアル ツリーから子を削除するだけで WPF がリソースを再利用するのかはわかりません。上記のリンクされた議論は言及していません。最初の説明で述べたように、上記の手法は、特定のイベントにフックするか、他のアプリケーション固有のロジックを使用することで補うことができます。

于 2012-03-10T20:55:02.953 に答える