Ein-Zeilen-Zusammenfassung: Was ist die beste Vorgehensweise zum Abhängen von Ereignishandlern, die im Konstruktor eines Benutzersteuerelements in Silverlight2 erstellt wurden?Wann sollten Ereignisse in Silverlight ausgehängt werden?
Hintergrund: Ich bin gerade dabei, eine Line-of-Business-Anwendung in Silverlight2 zu erstellen. Da Silverlight ein Browser-Plugin ist, gibt es kein Konzept für ein Fenster - alles wird in UserControls gemacht. Die Art, wie ich verschiedene "Formulare" in der Anwendung handhabe, ist eine Benutzersteuerung auf oberster Ebene, die eine Viewbox enthält. Um verschiedene Formulare anzuzeigen, setze ich die Child-Eigenschaft der Viewbox auf verschiedene UserControls. Meine App verfügt über eine Singleton PageManager-Klasse, die zum Öffnen und Schließen von Formularen aufgerufen wird. Die Formulare (UserControls) sind in einem Stapel gespeichert. Wenn Sie ein Formular öffnen, wird es oben auf den Stapel gelegt. Wenn Sie es schließen, wird es vom Stapel entfernt und der darunter liegende angezeigt.
Ich versuche, das Model-View-ViewModel-Muster zu folgen. In jedem Formular (abgeleitet von UserControl) habe ich ein ViewModel, das alle Daten für die Ansicht verwaltet. Das ViewModel macht Ereignisse verfügbar, sodass die Benutzeroberfläche benachrichtigt werden kann, wenn Vorgänge wie Laden und Speichern abgeschlossen sind.
In meiner Form, ich subscribe im Konstruktor auf das Ereignis, nachdem ich das Ansichtsmodell
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);
}
Meine Frage ist haben: Nun, da ich auf dieses Ereignis abonniert haben, wenn entferne ich die Handler? Erstelle ich einen Destruktor und tue es dort, oder erzeugt das eine Hühner-und-Ei-Situation, in der der Müllsammler das Objekt nicht zerstören wird, bis alle Referenzen (dh die Event-Handler) verschwunden sind? Erstelle ich eine Schnittstelle, die die Formulare implementieren müssen, die eine UnhookEvents-Funktion angibt, die aufgerufen wird, wenn das Formular vom PageManager geschlossen wird?
Bearbeiten: Vielen Dank für die Antworten. Was ist mit der Situation, in der das ViewModel länger als das Formular (UserControl) dauert? Ein Teil meiner App erlaubt es Benutzern, eine ziemlich komplexe Struktur zu erstellen, aber in 95% der Fälle ist es viel einfacher. Ich habe zwei Formulare erstellt, die dasselbe ViewModel verwenden. Benutzer können damit beginnen, das einfache Formular auszufüllen und dann in den erweiterten Modus zu wechseln, der ein neues Formular erstellt und das ViewModel an dieses Formular weitergibt.
In dem einfachen Setup-Form:
private void AdvancedSessionSetupButton_Click(object sender, RoutedEventArgs e)
{
PageManager.GetPageManager().Close(this);
PageManager.GetPageManager().Open(new CreateSessionPage(this.ViewModel), "Create Session");
}
im erweiterten Setup-Form:
private void BasicSessionSetupButton_Click(object sender, RoutedEventArgs e)
{
PageManager.GetPageManager().Close(this);
PageManager.GetPageManager().Open(new CreateBasicSessionPage(this.ViewModel), "Create Session");
}
Nach PageManager.Close, die einzigen Dinge, Referenzierung der Form sind die Ereignisse innerhalb des Ansichtsmodell. Ich nehme an, dort sollte ich sie aushaken.
Typo, "descructor" –
Was passiert, wenn mein ViewModel länger als das UserControl dauert? (Ich werde die Frage bearbeiten, um zu zeigen, wie) – geofftnz
Wenn Ihr Modell länger als die Benutzersteuerung dauert, müssen Sie sich dann auch keine Gedanken über die Aufhebung machen. Das Modell sollte keinen Bezug zum Steuerelement haben. Wenn das Steuerelement den Gültigkeitsbereich verlässt, wird es Müll gesammelt und zeigt nicht mehr auf das Modell. –