我目前对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 - “Markup”和“Delegate”。但是,如果我从Loaded="formHost_Loaded"
删除了WindowsFormsHost
,我就不会在启动时获取。很明显为什么我没有得到“标记”对话框,但为什么这也删除了“委托”?我认为它与事件被调用的顺序有关(Window与其子项),但我很难搞清楚它。
注意:您可以将WindowsFormsHost替换为其他控件,它确实无关紧要 - 我只是将它用于其他一些测试。
答案 0 :(得分:0)
Loaded事件处理程序在调用任何事件处理程序之前确定,因为Loaded事件从树顶部开始有效地全部广播。由于您在WPF确定需要调用哪些处理程序后添加了处理程序,因此将忽略它。
这可以使用Reflector进行验证。具体来说,BroadcastEventHelper.BroadcastLoadedSynchronously方法将使用LoadedEvent路由事件调用BroadcastEventHelper.BroadcastEvent方法。
BroadcastEvent方法首先收集可视树中具有Loaded事件处理程序的所有对象,然后遍历并引发这些对象上的事件。