【问题标题】:Adding and removing a user control from the visual tree raises Unloaded event but not Loaded event在可视化树中添加和删除用户控件会引发 Unloaded 事件,但不会引发 Loaded 事件
【发布时间】:2019-09-11 02:40:47
【问题描述】:

我注意到,如果用户控件(或任何框架元素)立即从可视化树中添加和删除,则永远不会引发 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 方法?有没有关于这种行为的文档?

【问题讨论】:

  • 根据您的代码,loaded 事件不会被触发,因为它已经在您构造 UserControl 控件时重新构造 -> this.control = new UserControl();
  • 有一个 IsLoaded 属性,您可以检查它是否已经发生。
  • @Doedoe Loaded 不会在施工时被解雇。
  • @SeanO'Neil IsLoaded 属性仅支持最新版本的操作系统。此外,我的问题是关于(错误)行为,一种类似黑客的解决方法。
  • @MehrzadChehraz,你能分享一下 xaml 代码吗?

标签: c# xaml uwp


【解决方案1】:

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

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

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

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

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

从语义上讲,您会看到如何卸载尚未加载的内容。将“加载”事件视为“完全加载”,将“加载”事件视为“部分加载”。无论这种行为给您带来了什么现实问题,请查看“Loading”事件而不是“Loaded”事件。

【讨论】:

  • 感谢您的回答。这正是我的想法,但我正在寻找有助于理解它如何工作以找到优雅解决方案的文档。加载事件也不起作用。只需将 Loaded 替换为 Loading,它就不会触发。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-22
  • 1970-01-01
  • 1970-01-01
  • 2011-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多