2010-08-06 3 views
28

Um Tab-basierte Umgebung in WPF zu implementieren, müssen wir unsere WPF Form Benutzersteuerung konvertieren Tab-basierte Umgebung zu erreichen, aber wenn dies zu tun, loaded event der Benutzerkontrolle wird two times genannt.Loaded-Ereignis eines WPF-Benutzersteuer Feuer zweimal

Bei der Suche im Internet verwiesen auch andere Leute auf dieses Problem. Wie können wir sicherstellen, dass das geladene Ereignis nur einmal aufgerufen wird, denn wenn es mehrmals aufgerufen wird, erfolgt die Initialisierung der Steuerelemente mehrmals.

Dank

+0

Ich habe versucht, dies in einem leeren .NET 4.0 WPF-Anwendung und das Loaded-Ereignis nur einmal abgefeuert zu reproduzieren. Haben Sie versucht, den Aufruf-Stack zu überprüfen, um festzustellen, ob in .NET Framework möglicherweise etwas Ungewöhnliches vor dem Laden des Loaded-Ereignisses vor sich geht? –

+0

Platzieren Sie Ihr Benutzersteuerelement in einem Registersteuerelement, und Sie können das Problem beim Wechseln der Registerkarten reproduzieren. – Eternal21

Antwort

36

Wie in diesen blog erläuterte, wird das Loaded-Ereignis ausgelöst, wenn jemals eine Steuer wird gerade gerendert (dh zum visuellen Baum hinzugefügt).

Es gibt mehrere Steuerelemente, die dazu führen, dass die Steuerung mehrmals geladen/entladen wird. Zum Beispiel rendert das native WPF TabControl nur den Inhalt der ausgewählten Registerkarte. Wenn Sie also eine neue Registerkarte auswählen, wird der Inhalt der zuvor ausgewählten Registerkarte gelöscht. Wenn Sie auf die zuvor ausgewählte Registerkarte klicken, wird der Inhalt neu geladen.

Eine Umgehung besteht darin, einen Boolean zu verwenden, um zu kennzeichnen, ob Sie Ihr Steuerelement bereits initialisiert haben, wie von anderen vorgeschlagen. Alternativ können Sie möglicherweise das Ereignis Initialized stattdessen verwenden.

+0

Ich verwende "ItemsSource" von TabControl, um mehrere Registerkarten zu binden, und verwende "DataTemplate", um ViewModel an die Registerkartenansichten zu binden. In meinem Fall wird nicht nur das 'Loaded'-Ereignis erneut ausgelöst, sondern auch der ** Konstruktor ** der Registerkartenansicht wird erneut aufgerufen. Es sieht so aus, als würde WPF meine Tab-Kontrolle jedes Mal neu erstellen, wenn ich die Registerkarte wechsle. – Felix

2

Legen Sie eine loaded Flagge im Fall, und, wenn das Flag bereits gesetzt worden ist, nichts tun.

+0

Vielen Dank für Ihren Vorschlag, ist dies wirklich ein echtes Problem und geladene Ereignis zweimal aufgerufen wegen Registerkarte –

-3

Eigentlich gibt bereits eine IsLoaded Eigenschaft ist, so dass Sie diese Zeile am Anfang der geladenen Event-Handler hinzufügen:

If Me.IsLoaded Then Return 
+2

Macht nichts, das funktioniert nicht. Sie müssen Ihre eigene Eigenschaft verwenden. –

+7

Sie sollten Ihre Antwort löschen, um die Dinge sauber zu halten. – DuckMaestro

+1

Im Loaded-Ereignishandler ist die IsLoaded-Eigenschaft offensichtlich immer wahr. – Pejman

11

Ihr Routingereignishandler kann (und sollte) sich selbst aus dem Loaded-Hook entfernen, als das Erste, was er tut.

public class MyClass : Window 
{ 
    public MyClass() 
    { 
     Loaded += MyLoadedRoutedEventHandler; 
    } 

    void MyLoadedRoutedEventHandler(Object sender, RoutedEventArgs e) 
    { 
     Loaded -= MyLoadedRoutedEventHandler; 
     /// ... 
    } 
};