从可视树中添加和删除用户控件会引发Unloaded事件,但不会引发Loaded事件

时间:2019-04-21 18:03:42

标签: c# xaml uwp

我注意到,如果立即从可视化树中添加和删除用户控件(或任何Framework元素),则永远不会引发Loaded事件,而总是引发Unloaded事件。

要重现该问题,请创建一个空白的UWP项目,将以下XAML和代码添加到MainPage中:

<Page ...>
    <Grid>
      <StackPanel>
         <Button Click="Button_Click" Content="Click Me"/>
         <Border x:Name="border"/>
      </StackPanel>
    </Grid>
</Page>

后面的代码:

public MainPage() {
     this.InitializeComponent();
     this.control = new UserControl();
     this.control.Loaded += OnLoaded;
     this.control.Unloaded += OnUnloaded;
  }
  private void Button_Click(object sender, RoutedEventArgs e) {
     this.border.Child = this.control;
     this.border.Child = null;
  }
  private void OnLoaded(object sender, RoutedEventArgs e) {
     System.Diagnostics.Debug.WriteLine("Loaded.");
  }
  private void OnUnloaded(object sender, RoutedEventArgs e) {
     System.Diagnostics.Debug.WriteLine("Unloaded");
  }

多次单击按钮将显示以下输出:

Unloaded
Unloaded
Unloaded
Unloaded
Unloaded
Unloaded
Unloaded

FrameworkEvent.Loaded(MSDN):

  

在构建FrameworkElement并将其添加到   对象树,并准备进行交互

FrameworkEvent.Unloaded(MSDN):

  

此对象不再连接到主对象树时发生。

这里到底发生了什么?如果未立即将控件添加到可视树中,因为该控件已被立即删除,为什么调用Unloaded方法?是否有任何有关此行为的文档?

1 个答案:

答案 0 :(得分:0)

这实际上不是编程问题,而是对Microsoft开发人员使用的语义的批评。我会用一个比喻回答。我本来会对此发表评论,但它太长了。

在飞机上装载行李很慢。我必须一次做一个袋子。卸载是即时的,我拉了一个杠杆,它们全部掉下来了。

当我开始在飞机上装载第一件行李时,我大声喊着“正在装载!” (“加载”事件)。

当我完成所有行李的装载后,我大喊“已装载”。 (“已加载”事件)。

如果接到电话告诉我航班已取消,我将拉杆并取出已经放在那里的所有行李,然后大喊“卸载”(“卸载”事件)。不管我是否真的已经完成了所有行李的装卸都无关紧要。我已经开始加载后将其卸载。

因此从语义上看,您将看到如何卸载尚未加载的内容。将“已加载”事件视为“已完全加载”,将“正在加载”事件视为“已部分加载”。无论此行为导致您遇到什么现实生活中的问题,请查看“正在加载”事件,而不是“已加载”事件。