我有一个继承自另一个类的类,该类具有非虚拟属性(“Controls”)。
由于我无法覆盖此属性,因此我使用与我的属性关联的“new”关键字。
在运行时,在正确的上下文中按照我的意愿调用此属性。
当我从设计师打开表单时,设计师调用base.Controls而不是我的“new”控件。
我是否遗漏了某些内容,或者这只是winforms设计师中的错误行为?
编辑,添加了相关代码以获得更多解释。我有以下课程:
public partial class BauerGroupBox : ComponentFactory.Krypton.Toolkit.KryptonGroupBox
{
public BauerGroupBox()
: base()
{
}
public new Control.ControlCollection Controls
{
get
{
MessageBox.Show("GOT THERE");
return this.Panel.Controls;
}
}
}
当我在我的intializecomponent中找到以下代码时:
BauerGroupBox thisBox = new BauerGroupBox()
thisBox.Controls.Add(something)
当我在我的代码中添加一个新的'BauerGroupBox'时,它运行正常。但是,当我在设计器中打开我的代码时(即使在使用调试devenv时),也没有显示消息框,并且没有命中断点。
当我运行我的应用程序时,断点被击中。
答案 0 :(得分:3)
你错过了什么 - 你所描述的是正确的行为。
解决方法是在调用Controls
后立即重新填充新的InitializeComponent()
媒体资源。像这样:
public MyForm() {
InitializeComponent();
this.Controls.AddRange( base.Controls );
}
但是,为什么要尝试“覆盖”Controls
属性?您之后有什么新的,非标准的行为?我相信还有更好的选择。
答案 1 :(得分:1)
您误解了新关键字的工作原理。 New不会覆盖属性,它会隐藏它。如果您引用该对象作为其基本元素,它仍将调用基本属性,而不是新属性。使用新方法的唯一方法是将其引用为新方法。即
public class A {
public A1 {get;set;}
}
public class B : A {
public new A1 {get;set;}
}
B b = new B();
A a = b;
a.A1; // references A.A1
b.A1; // references B.A1
答案 2 :(得分:1)
我想我了解你的情况,所以让我解释一下设计师在做什么:
首先,在运行时,您正在有效地运行BauerGroupBox
控件的实例。 (也就是说,你也可能通过这个派生类型的引用访问Controls
属性,即BauerGroupBox
,并且正如@Mystere Man正确认为的那样,成员BauerGroupBox.Controls
隐藏了继承的成员(无论它在哪里定义) - 它都不会覆盖它。
问题是,在设计时,在<{strong> BauerGroupBox
控件的设计者中,您不是“正在运行”的实例BauerGroupBox
,而您designing
是基于ComponentFactory.Krypton.Toolkit.KryptonGroupBox
的原型,实际上是您“正在运行”的控件的类型。
我再说一遍,BauerGroupBox
的设计者没有运行BauerGroupBox
的实例,而是ComponentFactory.Krypton.Toolkit.KryptonGroupBox
的实例。设计师中不存在BauerGroupBox
,因为,好吧......你正在设计它!
现在,为此添加一点混淆(没有真的,如果你仔细考虑它就会非常简单),你会看到,如果你去任何其他控制的任何其他设计师,说一个表格,然后你拖放你的BauerGroupBox
的一个实例,并添加一些控件,你的消息框,是的,在这种情况下,就像在“运行时”的情况下,这意味着你是有效托管BauerGroupBox
...但在这种情况下,您没有设计BauerGroupBox
。
正如其他@Dai所提到的,如果您要做的是阻止人们向其添加控件,那么您应该遵循其他设计方案:例如,覆盖
protected virtual Control.ControlCollection CreateControlsInstance();
方法