1

子ウィンドウを起動するメイン ウィンドウがあります。その子ウィンドウは、カスタム ユーザー コントロールを動的に読み込みます。これらのユーザー コントロールのコンストラクターで、マスター オブジェクトを渡します。このマスター オブジェクトから、ユーザー コントロール固有のビューモデルが生成され、そのデータ コンテキストとして割り当てられます。

これらはすべて非常にうまく機能しています。ただし、子ウィンドウを閉じると、カスタム ユーザー コントロールの少なくとも一部がまだアクティブになっていることがわかりました。コントロール/ビューモデルをクリーンアップするにはどうすればよいですか? メインウィンドウが閉じられるまで、何も呼び出されないようです。デストラクタも、Dispatcher.ShutdownStarted もありません。Dispose も利用できません。終了イベントもありません。何も見つかりません。

ウィンドウが閉じられた後に適切にクリーンアップするために何をすべきか知っている人はいますか?

4

1 に答える 1

1

ビューとビューモデルを作成する責任は何か、何かを閉じることができるかどうかを決定する責任は何か、などを正確に考える必要があると思います。

通常、何かを作成したものを破壊するのは良い考えです。したがって、子ウィンドウがカスタム ユーザー コントロールを作成している場合は、おそらくそれらを削除する必要があります。ただし、どのオブジェクトにも参照 (または強力なイベント サブスクリプション) がない場合は、最終的にはガベージ コレクションが必要になると思います。ファイナライザ/デストラクタを実装し、Debug.String を出力ウィンドウに出力して、これが最終的にいつ発生するかを確認できます。優れたメモリ プロファイラーも良い考えです。ただし、ViewModel がいつ閉じられたかを伝えるために、より正確な制御が必要になる可能性もあります。

シナリオで何が起こるべきかを正確に言うのは難しいです。これは、正確で特定の設定に本当に依存するためです。私のアプリケーションでのシナリオについて説明させてください。タブページに表示されていたいくつかのビューがありました。タブ ページには、タブを閉じるための X ボタンがあり、ビューには、リソースをクリーンアップするために .Dispose() を呼び出す必要があるホストされた Windows フォーム コントロールが含まれていました。ファイルメニューシステム。それで、最初は問題がありました...タブページがビューを削除するときに、ViewModelはどのようにコマンドからサブスクライブを解除しますか? WPF コントロールに含まれているビューは、それがいつ削除されたかをどのように認識しますか? これが私が思いついたものです

  1. タブページ自体は、ビューを閉じることができるかどうかをプログラムに伝えるべきではありません
  2. プログラム ロジックの場合にクロージング イベントをキャンセルする機能が必要でした (ファイルは保存されましたか? はい/いいえ/キャンセル)。
  3. 閉鎖されたときを検出する機能が必要だったので、その瞬間にクリーンアップ/登録解除できました

私の解決策は、Removable ブール値とブール値を返す (削除されたかどうかに関係なく) Remove() メソッドを公開する IRemovable というビューモデルにインターフェイスを実装することでした。私のタブ コントロールは、Removable が true の場合にのみ X ボタンを表示し、Tab Control の Closing は IRemovable ViewModel の Remove() を起動し、それが false を返した場合、ViewModel の Remove が false を返した場合、イベント args Canceled プロパティを true に設定しました。

したがって、ビュー モデルを削除すると、ユーザーに確認を求めるプロンプトが表示されたり、コマンドから登録解除されたりする可能性があります。ビューは Closed イベントを処理し、Windows フォーム コンポーネントなどで Dispose を呼び出すことができます (もちろん、View.DataContext がI取り外し可能)。

とにかく、これが正確な答えではないことはわかっていますが、自分の問題を解決する方法について考え出すのに役立つことを願っています

于 2012-10-29T20:52:53.833 に答える