2009-06-25 27 views
2

我目前對於FrameworkElement.Loaded事件的不同行爲非常困惑。我已經組建了一個演示這個小例子的應用程序。標記中的奇怪加載行爲與代碼

的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> 

代碼:

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"); 
     } 
    } 
} 

正因爲如此,當我運行的應用程序,我得到兩個直接MessageBox ES - 「標記」 和 「委派」。但是,如果我從WindowsFormsHost中刪除Loaded="formHost_Loaded",我就不會在啓動時啓動。顯然,爲什麼我沒有得到「標記」對話框,但爲什麼這也會刪除「委託」?我可以想象它與事件的調用順序(窗口對它的孩子)有關,但我很難搞清楚。

注意:您可以將WindowsFormsHost替換爲其他控件,這確實無關緊要 - 我只是將它用於其他一些測試。

回答

0

Loaded事件處理程序在調用它們中的任何一個之前就已確定,因爲Loaded事件從樹頂部開始一次有效地全部廣播。由於在WPF決定需要調用什麼處理程序之後添加了處理程序,因此將忽略它​​。

這可以使用反射器進行驗證。具體來說,BroadcastEventHelper.BroadcastLoadedSynchronously方法將使用LoadedEvent路由事件調用BroadcastEventHelper.BroadcastEvent方法。

BroadcastEvent方法首先收集具有Loaded事件處理程序的可視樹中的所有對象,然後循環並引發這些對象上的事件。