2009-06-25 10 views
2

Ich bin derzeit sehr durch das unterschiedliche Verhalten in Bezug auf die FrameworkElement.Loaded Ereignis verwirrt. Ich habe eine kleine Beispielanwendung zusammengestellt, die dies demonstriert.Odd Loaded Verhalten in Markup gegen Code

XAML:

<Window x:Class="WpfApplication1.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Window1" Height="300" Width="300" 
     Loaded="Window_Loaded"> 
    <Grid> 
     <TabControl> 
      <TabItem Header="Tab 1" /> 
      <TabItem Header="Tab 2" > 
       <WindowsFormsHost Name="formHost" Loaded="formHost_Loaded" /> 
      </TabItem> 
     </TabControl> 
    </Grid> 
</Window> 

Code:

using System.Windows; 

namespace WpfApplication1 
{ 
    public partial class Window1 : Window 
    { 
     public Window1() 
     { 
      InitializeComponent(); 
     } 

     private void Window_Loaded(object sender, RoutedEventArgs e) 
     { 
      formHost.Loaded += delegate 
      { 
       MessageBox.Show("Delegate"); 
      }; 
     } 

     private void formHost_Loaded(object sender, RoutedEventArgs e) 
     { 
      MessageBox.Show("Markup"); 
     } 
    } 
} 

Wie es ist, wenn ich die Anwendung ausführen ich zwei unmittelbare MessageBox es - "Markup" und "Delegate". Wenn ich jedoch Loaded="formHost_Loaded" aus dem WindowsFormsHost entferne, bekomme ich beim Start auch keinen. Es macht natürlich Sinn, warum ich den "Markup" -Dialog nicht bekomme, aber warum entfernt das auch den "Delegate"? Ich könnte mir vorstellen, dass es mit der Reihenfolge zu tun hat, in der die Ereignisse genannt werden (Fenster gegen seine Kinder), aber ich habe es schwer, es herauszufinden.

Hinweis: Sie können den WindowsFormsHost durch andere Steuerelemente ersetzen, es sollte wirklich keine Rolle spielen - ich habe es nur für ein paar andere Tests verwendet.

Antwort

0

Die Loaded-Event-Handler werden bestimmt, bevor einer von ihnen aufgerufen wird, da das Loaded-Ereignis effektiv auf einmal gesendet wird, beginnend am Anfang der Baumstruktur. Da Sie einen Handler hinzugefügt haben, nachdem WPF entschieden hat, welche Handler aufgerufen werden müssen, wird sie ignoriert.

Dies kann mit Reflektor überprüft werden. Insbesondere ruft die BroadcastEventHelper.BroadcastLoadedSynchronously-Methode die BroadcastEventHelper.BroadcastEvent-Methode mit dem LoadedEvent-Routingereignis auf.

Die BroadcastEvent-Methode sammelt alle Objekte in der visuellen Struktur, die zuerst einen Loaded-Ereignishandler haben, führt dann eine Schleife durch und löst die Ereignisse für diese Objekte aus.