在子构造函数的 InitializeComponent 完成后运行方法,而不在子类中隐式调用
我不确定这是否可能,但我希望能够做的是让父基类的所有子级运行基类中定义的方法,而不在子类中显式调用它。
换句话说,我想要实现的是这样的:
public class Parent
{
public Parent()
{
InitializeComponent();
Setup(); // not run here if this instance is a child of parent
}
protected void Setup()
{
// code that depends on InitializeComponent being called in
// both the parent and any Child's classes
}
}
public class Child : Parent
{
public Child()
{
InitializeComponent();
//Setup(); is invoked here, without having to explicitly
// invoke in all children of Parent
}
}
是否有一种模式可以实现这种行为,或者面向方面的编程可能是实现这一目标的一种方法?
I'm not sure if this is possible or not, but what I would like to be able to do is to have all Children of a Parent base class to run a method defined in the base class without explicitly invoking it in the child class.
In other words, what I'd like to achieve is something like this:
public class Parent
{
public Parent()
{
InitializeComponent();
Setup(); // not run here if this instance is a child of parent
}
protected void Setup()
{
// code that depends on InitializeComponent being called in
// both the parent and any Child's classes
}
}
public class Child : Parent
{
public Child()
{
InitializeComponent();
//Setup(); is invoked here, without having to explicitly
// invoke in all children of Parent
}
}
Is there a pattern that could enable this behaviour, or could perhaps Aspect Oriented Programming be a way to achieve this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您可以改为覆盖
Form.OnLoad
父表单的方法;它保证在表单显示之前被调用。You could instead override the
Form.OnLoad
method of the parent form; it's guaranteed to be called just before the Form is shown.我认为您只想覆盖
OnLoad
方法:父子组件初始化时调用。
不要忘记调用
base.OnLoad
以便Load
事件处理程序(如果有)接收该事件。I think you just want to override
OnLoad
method:It is called when both parent and child components are initialized.
Don't forget to call
base.OnLoad
so thatLoad
event handlers, if any, receive the event.Child 的构造函数将自动调用 Parent 的构造函数(实际上,在调用其自己的代码之前),因此在上面的情况下,Setup 将始终在 Child 类中调用(并且 InitializeComponent 将被调用两次)。
The constructor of Child will automatically call the constructor of Parent (before its own code gets called, in fact), so in your situation above, Setup will always be called in the Child class (and InitializeComponent will be called twice).
在
Load
事件或OnLoad
中运行代码通常是最糟糕的解决方案。如果您想在表单加载后运行一次代码,您可以使用
Shown
事件,否则,如果您有长时间运行的代码(控件依次显示),则表单看起来会滞后且无响应。如果您确实想在子构造函数之后但在加载事件之前运行代码,则重写 OnHandleCreated 是您的最佳选择。
然而:(至少)还有一件事不起作用。我有一个表单基类,它设置特定的启动位置/大小,无论子表单定义什么。我所做的每一次努力都失败了,或者表格在一瞬间出现在错误的位置。这就是我解决它的方法:
这是棘手的部分:设置大小后,它会以某种方式在加载过程中的某个点上恢复。如果您调用 Screen.FromControl(form) ,也会发生同样的情况。我想是因为
Screen.FromControl
最终调用Screen.FromHandle
并且这将导致创建句柄。但我想它也会做其他事情,因为如果我在 OnHandleCreated 方法中运行上述代码(当然在调用 base.OnHandleCreated 之后),它不会得到所需的结果结果。因此,我在Screen.FromControl
之后再次设置了大小,最后一行只是使表单在屏幕上居中。Running code in the
Load
event orOnLoad
is often the worst solution.If you want to run code once after the form load you can use
Shown
event, otherwise the form looks laggy and unresponsive you you have long running code (controls are shown one after another).If you really want to run code after the child constructor but before the load event, overriding OnHandleCreated is your best choice.
However: There is (at least) one thing left that won't work. I had a form base class that set a specific startup position / size regardless of what the child form defined. Every effort I made failed or the form was visible on the wrong location for a split second. This is how I solved it:
Here is the tricky part: After yo set the size, it somehow gets reverted on some point in the load process. The same thing happens if you call
Screen.FromControl(form)
. I suppose becauseScreen.FromControl
eventually callsScreen.FromHandle
and that will cause the handle to be created. But I suppose it does something else, too because if I run the above code in theOnHandleCreated
method (after callingbase.OnHandleCreated
of course) it won't get the desired result. Because of this I set the size again afterScreen.FromControl
the last line is just to center the form on the screen.