1 行の要約: Silverlight2 の UserControl のコンストラクターで作成されたイベント ハンドラーをアンフックするためのベスト プラクティスは何ですか?
背景: 現在、Silverlight2 で基幹業務アプリケーションを構築しています。Silverlight はブラウザー プラグインであるため、ウィンドウの概念はありません。すべては UserControls 内で行われます。アプリケーションでさまざまな「フォーム」を処理する方法は、Viewbox を含む最上位のユーザー コントロールを使用することです。別のフォームを表示するには、Viewbox の Child プロパティを別の UserControls に設定します。私のアプリには、フォームを開閉するために呼び出されるシングルトン PageManager クラスがあります。フォーム (UserControls) はスタックに格納されます。フォームを開くとスタックの一番上に置かれ、フォームを閉じるとスタックから削除され、その下のフォームが表示されます。
Model-View-ViewModel パターンに従おうとしています。各フォーム (UserControl から派生) には、View のすべてのデータを管理する ViewModel があります。ViewModel はイベントを公開するため、読み込みや保存などの操作が完了したときに UI に通知できます。
私のフォームでは、ViewModel を取得した後、コンストラクターでイベントをサブスクライブします。
public partial class MyPage : UserControl
{
public MyViewModel ViewModel{get; set;}
// other constructors, which create the viewmodel and call the constructor below.
public MyPage(MyViewModel viewModel)
{
InitializeComponent();
ViewModel = viewModel;
this.LayoutRoot.DataContext = this.ViewModel;
// subscribe to event so we can do stuff
this.ViewModel.LoadCompleted += new MyViewModel.LoadCompletedEventHandler(ViewModel_LoadCompleted);
}
私の質問は次のとおりです。このイベントをサブスクライブしたので、いつハンドラーを削除しますか? デストラクタを作成してそこで実行しますか?それとも、ガベージ コレクタがすべての参照 (つまり、イベント ハンドラ) がなくなるまでオブジェクトを破棄しない鶏と卵の状況を作り出しますか? PageManager によってフォームが閉じられたときに呼び出される UnhookEvents 関数を指定する、フォームが実装する必要があるインターフェイスを作成する必要がありますか?
編集:返信ありがとうございます。ViewModel がフォーム (UserControl) よりも長く続く状況はどうですか? 私のアプリの一部では、ユーザーは非常に複雑な構造を作成できますが、95% のケースでは、はるかに単純です。私がやったことは、同じViewModelを使用する2つのフォームを作成することでした. ユーザーは単純なフォームへの入力を開始してから、ViewModel を渡して新しいフォームを作成する詳細モードに切り替えることができます。
簡単なセットアップ フォームの場合:
private void AdvancedSessionSetupButton_Click(object sender, RoutedEventArgs e)
{
PageManager.GetPageManager().Close(this);
PageManager.GetPageManager().Open(new CreateSessionPage(this.ViewModel), "Create Session");
}
詳細設定フォームで:
private void BasicSessionSetupButton_Click(object sender, RoutedEventArgs e)
{
PageManager.GetPageManager().Close(this);
PageManager.GetPageManager().Open(new CreateBasicSessionPage(this.ViewModel), "Create Session");
}
PageManager.Close の後、フォームを参照しているのは ViewModel 内のイベントだけです。私はそれが私がそれらを外す必要がある場所だと思います。