C#Winforms Designer调用基本属性而不是“新”属性?

时间:2012-09-19 16:02:17

标签: c# winforms override windows-forms-designer

我有一个继承自另一个类的类,该类具有非虚拟属性(“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时),也没有显示消息框,并且没有命中断点。

当我运行我的应用程序时,断点被击中。

3 个答案:

答案 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();

方法