WPF,派生类比基类率先引发Loaded事件?

货郎大叔 2017-11-24 05:16:38

public class BaseCustomControl:Control
{
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
Loaded += BaseCustomControl_Loaded;
}
private void BaseCustomControl_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
throw new NotImplementedException();
}
}
public class CustomControl3 : BaseCustomControl
{
static CustomControl3()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl3), new FrameworkPropertyMetadata(typeof(CustomControl3)));
}
public CustomControl3()
{
Loaded += CustomControl3_Loaded;
}
private void CustomControl3_Loaded(object sender, RoutedEventArgs e)
{
throw new NotImplementedException();
}
}

在上面的代码中,CustomControl3继承自BaseCustomControl,分别在BaseCustomControl_Loaded方法和CustomControl3_Loaded方法处设置断点,可以看到,率先执行的是CustomControl3_Loaded方法,难道派生类比基类率先引发Loaded事件
...全文
726 36 打赏 收藏 转发到动态 举报
写回复
用AI写文章
36 条回复
切换为时间正序
请发表友善的回复…
发表回复
闭包客 2017-12-12
  • 打赏
  • 举报
回复
从设计上来看,多播事件的执行和顺序无关,但是从 .net event 的具体实现上,就是顺序执行的。而且是按照订阅顺序执行的。 也就是说,这个执行顺序,和是不是 WPF 没有关系,.net 都是这样的。 另外,我看到有谈论到 OnLoad 虚函数和 Loaded 事件的差异问题。这个我在设计自己的框架的时候,知道了 .net 框架这样设计的原因。在 web form 里面,还有一个自动订阅事件的机制,如果有人感兴趣,我也可以展开讨论。
lindexi_gd 2017-12-12
  • 打赏
  • 举报
回复
我研究了 UWP 的初始化 [win10 uwp 自定义控件初始化](https://lindexi.oschina.io/lindexi/post/win10-uwp-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%8E%A7%E4%BB%B6%E5%88%9D%E5%A7%8B%E5%8C%96.html )发现控件初始化是 构造-OnInitialized-Loaded
货郎大叔 2017-12-12
  • 打赏
  • 举报
回复
引用 34 楼 closurer 的回复:
从设计上来看,多播事件的执行和顺序无关,但是从 .net event 的具体实现上,就是顺序执行的。而且是按照订阅顺序执行的。
原来是按照订阅顺序执行的,这样的话,楼顶的问题就能解释得通了。
货郎大叔 2017-12-12
  • 打赏
  • 举报
回复
引用 32 楼 sr32r345 的回复:
可以看出,派生类的Loaded比基类先执行。如果把基类的事件订阅放在BaseCustomControl构造函数中,结果却是BaseCustomControl_Loaded比CustomControl3_Loaded先执行。 我也不是挑刺,也就是想知道其中的讲究.....
货郎大叔 2017-12-11
  • 打赏
  • 举报
回复
引用 31 楼 xuzuning 的回复:
其实你只需要测试一下 BaseCustomControl 的 OnApplyTemplate 事件是在何时触发的就可以了

我在各个地方设置了断点,



测试得执行顺序如下:
1、public CustomControl3()
2、BaseCustomControl的OnApplyTemplate方法
3、Window_Loaded
4、CustomControl3_Loaded
5、BaseCustomControl_Loaded

可以看出,派生类的Loaded比基类先执行。如果把基类的事件订阅放在BaseCustomControl构造函数中,结果却是BaseCustomControl_Loaded比CustomControl3_Loaded先执行。
我也不是挑刺,也就是想知道其中的讲究.....
货郎大叔 2017-12-10
  • 打赏
  • 举报
回复
还是没有让我懂,有没有对WPF研究比较深入的朋友解答下。
xuzuning 2017-12-10
  • 打赏
  • 举报
回复
其实你只需要测试一下 BaseCustomControl 的 OnApplyTemplate 事件是在何时触发的就可以了
圣殿骑士18 2017-12-04
  • 打赏
  • 举报
回复
引用 25 楼 daixf_csdn 的回复:
[quote=引用 22 楼 sr32r345 的回复:] [quote=引用 21 楼 daixf_csdn 的回复:] 7楼的执行顺序正常,这个就是因为绑定是放在构造方法里的,所以后面执行都对了。 而把绑定放OnApplyTemplate()中就有问题,就是因为OnApplyTemplate()被执行的时机问题。你说过OnApplyTemplate()执行在CustomControl3_Loaded方法之前执行的。 我们就可以推演一下执行顺序:(关键要理解窗体Loaded是如何执行的,它实际上就是一个委托的实现,由Onload()方法调用的)
你的意思是派生类的Onload方法比基类的OnApplyTemplate方法先执行? 就拿Button来说,MSDN页面怎么找不到Onload方法呢?[/quote] 哪个比哪个先执行,你看我的图了吗?竟然得出这种结论?还是说你还不会看时序图。我对你什么时候调用OnApplyTemplate只是猜测,因为你从来没说过在哪里调用的OnApplyTemplate。[/quote] 那应该也不影响结论。
货郎大叔 2017-12-04
  • 打赏
  • 举报
回复
引用 27 楼 lkf181 的回复:
事件管道 事件管道
这是?
货郎大叔 2017-12-03
  • 打赏
  • 举报
回复
引用 21 楼 daixf_csdn 的回复:
7楼的执行顺序正常,这个就是因为绑定是放在构造方法里的,所以后面执行都对了。 而把绑定放OnApplyTemplate()中就有问题,就是因为OnApplyTemplate()被执行的时机问题。你说过OnApplyTemplate()执行在CustomControl3_Loaded方法之前执行的。 我们就可以推演一下执行顺序:(关键要理解窗体Loaded是如何执行的,它实际上就是一个委托的实现,由Onload()方法调用的)
你的意思是派生类的Onload方法比基类的OnApplyTemplate方法先执行? 就拿Button来说,MSDN页面怎么找不到Onload方法呢?
货郎大叔 2017-12-03
  • 打赏
  • 举报
回复
引用 25 楼 daixf_csdn 的回复:
哪个比哪个先执行,你看我的图了吗?竟然得出这种结论?还是说你还不会看时序图。我对你什么时候调用OnApplyTemplate只是猜测,因为你从来没说过在哪里调用的OnApplyTemplate。
我看你在23楼就谈到Form,不会是以为这是Winform吧,我说的是WPF哦,OnApplyTemplate方法不是我主动调用的、。
圣殿骑士18 2017-12-03
  • 打赏
  • 举报
回复
引用 22 楼 sr32r345 的回复:
[quote=引用 21 楼 daixf_csdn 的回复:] 7楼的执行顺序正常,这个就是因为绑定是放在构造方法里的,所以后面执行都对了。 而把绑定放OnApplyTemplate()中就有问题,就是因为OnApplyTemplate()被执行的时机问题。你说过OnApplyTemplate()执行在CustomControl3_Loaded方法之前执行的。 我们就可以推演一下执行顺序:(关键要理解窗体Loaded是如何执行的,它实际上就是一个委托的实现,由Onload()方法调用的)
你的意思是派生类的Onload方法比基类的OnApplyTemplate方法先执行? 就拿Button来说,MSDN页面怎么找不到Onload方法呢?[/quote] 哪个比哪个先执行,你看我的图了吗?竟然得出这种结论?还是说你还不会看时序图。我对你什么时候调用OnApplyTemplate只是猜测,因为你从来没说过在哪里调用的OnApplyTemplate。
圣殿骑士18 2017-12-03
  • 打赏
  • 举报
回复
一般没有必要用Onload,我看到有些人喜欢用重写Onload来代替Loaded事件,我认为是过度使用了。 重写Onload只有你确定想改变微软对winform窗体初始化机制,做一些定制的时候才需要用,比如你想在Loaded事件前,再加一个自己的什么事件。否则不要用,能简单就不要复杂。
圣殿骑士18 2017-12-03
  • 打赏
  • 举报
回复
OnLoad是窗体方法,跟button无关。微软本来就是封装了Onload而暴露Loaded事件,是为了使机制更好理解,不公开Onload也正常。 你在Form里override一下OnLoad,会有所发现。
圣殿骑士18 2017-12-02
  • 打赏
  • 举报
回复
7楼的执行顺序正常,这个就是因为绑定是放在构造方法里的,所以后面执行都对了。

而把绑定放OnApplyTemplate()中就有问题,就是因为OnApplyTemplate()被执行的时机问题。你说过OnApplyTemplate()执行在CustomControl3_Loaded方法之前执行的。
我们就可以推演一下执行顺序:(关键要理解窗体Loaded是如何执行的,它实际上就是一个委托的实现,由Onload()方法调用的)
货郎大叔 2017-12-01
  • 打赏
  • 举报
回复
没有人知道吗
正怒月神 2017-11-29
  • 打赏
  • 举报
回复
引用 15 楼 sr32r345 的回复:
[quote=引用 13 楼 hanjun0612 的回复:] 但你还是要把你的调试过程贴出来,然后才能分析。 不过 OnApplyTemplate和load的执行顺序,据说是不分先后的?? https://www.cnblogs.com/wodehuajianrui/archive/2008/09/12/1290077.html
就是在各个方法点设置断点啊 [/quote] 可能是网上说的,执行不分先后的问题?
exception92 2017-11-29
  • 打赏
  • 举报
回复
引用 16 楼 sr32r345 的回复:
[quote=引用 14 楼 duanzi_peng 的回复:]只有在窗体的Loaded执行完毕才会执行OnApplyTemplate重载方法,因为它要重写一些样式模板之类的东西。

可事实上,OnApplyTemplate比窗体的Loaded先执行诶[/quote]
贴出你的输出测试结果,这是我这边的输入结果:
货郎大叔 2017-11-29
  • 打赏
  • 举报
回复
引用 17 楼 duanzi_peng 的回复:
贴出你的输出测试结果,这是我这边的输入结果:

exception92 2017-11-28
  • 打赏
  • 举报
回复
public override void OnApplyTemplate() { base.OnApplyTemplate(); Loaded += BaseCustomControl_Loaded; } 你把Loaded方法放到 OnApplyTemplate()中,当然派生类先执行,你放到基类的构造函数中,肯定是先引发基类的loaded事件。只有在窗体的Loaded执行完毕才会执行OnApplyTemplate重载方法,因为它要重写一些样式模板之类的东西。
加载更多回复(15)
在Windows系统中,notepad.exe(记事本)是一个“经典的”、“简洁的”文本编辑器。这个软件,没有华丽的外观,也没有繁杂的功能,仅仅是一个文本编辑小软件。虽然经过Windows系统数十年的变换,但它却保持着永恒姿态,数十年来几乎不曾改变过。曾经,VS中的经典DEMO中,就有它的身影,一个新建的项目,就藏有一个新建的“记事本”。然而,在WPF的项目中,“记事本”却消失的无影无踪,也许是很容易实现,也许是为了革新,而不愿再传承“经典”。确实,使用WPF技术再次让“记事本”复活,确实也是一件非常容易的事情。但是,如果,使用WPF技术,再搭配当下非常流行的MVVM模式呢?复活“记事本”的难度却陡然上升至很多WPF程序员为之默默叹气。而,MVVM模式是掌握WPF的最顶级技术,MVVM模式拥有的无尽的优势,让WPF相对于过往的编程模式来说,是一种革命性的创新,从而也成为大中型WPF项目中必须的模式。但,学习难度。。。。。。在这个《WPF记事本开发详解》的课程中,赵老师带领你在WPF中,从零开始一步步构建MVVM模式,直到让你亲自以WPF+MVVM的方式,让这个经典的“记事本”软件从你的手中“复活”。在课程中,赵老师会详细讲解WPF和MVVM中的各种技巧,让你从此爱上WPF+MVVM编程。

110,549

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧