Sometimes WPF raise unload event twice. In this case, it happens when a logical tree is build all by myself. Why unload twice? It really confused me.
Any help would be appreciated! The repo: walterlv/why-unload-twice @ GitHub
Why the _problemChild
unloaded twice?
How to reproduce it ?
- Clone this repository;
- Run/Debug;
- Click Add Child button several times;
- Every time you click Delete Child, you’ll got Content Unloaded output twice.
Key points
- A non-generic style is added.
- When removing an FrameworkElement from a visual tree, it is also been removed from a logical tree at the same time.
- The visual tree and the logical tree is different.
Key points(zh-CHS) - 复现此问题的关键
- 为一个
TemplatedControl
(CustomControl
) 定制非默认模板(不放在Generic.xaml
中的模板); - 这个控件包含视觉子级和逻辑子级,并且这两个不是同一个对象;
- 将这个控件同时从视觉树和逻辑树中移除(两个移除顺序不重要,但一定是无中断的);
这时你会观察到从这个控件的逻辑子级开始向所有子节点递归引发 Unloaded
事件,然后又从这个控件本身开始向所有子节点递归引发 Unloaded
事件,于是所有子节点都会连续发生两次 Unloaded
事件。
Key points(zh-CHT) - 復現此問題的關鍵
- 為一個
TemplatedControl
(CustomControl
) 定制非默認模板(不放在Generic.xaml
中的模板); - 這個控件包含視覺子級和邏輯子級,並且這兩個不是同一個對象;
- 將這個控件同時從視覺樹和邏輯樹中移除(兩個移除順序不重要,但一定是無中斷的);
這時你會觀察到從這個控件的邏輯子級開始向所有子節點遞歸引發Unloaded
事件,然後又從這個控件本身開始向所有子節點遞歸引發Unloaded
事件,於是所有子節點都會連續發生兩次Unloaded
事件。
Stacks of this issue
When a non-generic style of Child
is added, the Unloaded
event will be raised of these two operations.
Removing from visual tree with non-generic style
Removing from logical tree with non-generic style
When only the generic style of Child
is defined, the Unloaded
event will be raised of only one operations.
Removing from visual tree with generic style
本文会经常更新,请阅读原文: https://blog.walterlv.com/wpf/2017/09/19/why-unload-twice.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 吕毅 (包含链接: https://blog.walterlv.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 ([email protected]) 。