2009-06-25 5 views
2

Je suis actuellement très confus par le comportement différent concernant l'événement FrameworkElement.Loaded. J'ai mis en place un petit exemple d'application qui le démontre.Comportement impairs dans le balisage par rapport au 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"); 
     } 
    } 
} 

Comme il est, quand je lance l'application, je reçois deux MessageBox immédiates es - "balisage" et "délégué". Si, cependant, je supprime Loaded="formHost_Loaded" du WindowsFormsHost, je ne reçois ni au démarrage. Il est évident que je n'ai pas le dialogue "Markup", mais pourquoi cela supprime-t-il aussi le "Delegate"? J'imagine que cela a à voir avec l'ordre dans lequel les événements sont appelés (Window contre ses enfants), mais j'ai du mal à le comprendre.

Remarque: Vous pouvez remplacer WindowsFormsHost par d'autres contrôles, cela ne devrait vraiment pas avoir d'importance - je l'utilisais juste pour quelques tests supplémentaires.

Répondre

0

Les gestionnaires d'événements Loaded sont déterminés avant que l'un d'entre eux soit appelé, car l'événement Loaded est effectivement diffusé en une fois en commençant en haut de l'arborescence. Depuis que vous avez ajouté un gestionnaire après que WPF a décidé quels gestionnaires doivent être appelés, il est ignoré.

Ceci peut être vérifié en utilisant Reflector. Plus précisément, la méthode BroadcastEventHelper.BroadcastLoadedSynchronously appellera la méthode BroadcastEventHelper.BroadcastEvent avec l'événement routé LoadedEvent. La méthode BroadcastEvent rassemble d'abord tous les objets de l'arborescence visuelle qui ont un gestionnaire d'événements Loaded, puis boucle et déclenche les événements sur ces objets.

Questions connexes