2

我有一个类继承自另一个类,该类具有非虚拟属性(“控件”)。

由于我无法覆盖此属性,因此我使用与我的属性关联的“新”关键字。

在运行时,在正确的上下文中按我的意愿调用此属性。

当我从设计器打开我的表单时,设计器调用 base.Controls 而不是我的“新”控件。

我是否遗漏了什么,或者这只是 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 时),消息框也不会显示,并且断点也不会命中。

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

4

3 回答 3

3

你错过了一些东西 - 你所描述的是正确的行为。

解决方法是Controls在调用InitializeComponent(). 像这样:

public MyForm()  {
    InitializeComponent();
    this.Controls.AddRange( base.Controls );
}

但是,您为什么要尝试“覆盖”该Controls属性?你追求什么新的、非标准的行为?我相信有更好的选择。

于 2012-09-19T16:07:05.177 回答
1

我想我理解你的情况,所以让我解释一下设计师在做什么:

首先,在运行时,您实际上是在运行BauerGroupBox控件的一个实例。(也就是说,您也很可能Controls通过此派生类型的引用访问该属性,即BauerGroupBox,并且正如@Mystere Man 正确论证的那样,该成员BauerGroupBox.Controls隐藏了继承的成员(无论它最后定义的位置) - 它没有覆盖它。

有问题的问题是,在设计时,在控件的设计器中BauerGroupBox,您不是“运行”的实例BauerGroupBox,而是designing基于原型ComponentFactory.Krypton.Toolkit.KryptonGroupBox,这实际上是您正在“运行”的控件的类型.

我再说一遍, 的设计者BauerGroupBox没有BauerGroupBox运行的实例,而是ComponentFactory.Krypton.Toolkit.KryptonGroupBox. 设计师中不BauerGroupBox存在,因为,嗯..你正在设计它!

现在,为了增加一点混乱(真的没有,如果你想一想,这一切都很简单,)你会看到,如果你去任何其他控件的任何其他设计者,说一个表单,然后你拖放一个你的实例BauerGroupBox,然后添加一些控件,你就会得到你的消息框,是的,在这种情况下,就像在“运行时”的情况下一样,这意味着你正在有效地托管一个BauerGroupBox......但是在这种情况下,你不是在设计BauerGroupBox

正如其他@Dai 提到的那样,如果您要阻止人们向其添加控件,那么您应该遵循其他设计计划:例如,覆盖

protected virtual Control.ControlCollection CreateControlsInstance();

方法。

于 2012-09-19T16:34:50.473 回答
1

您误解了新关键字的工作原理。New 不会覆盖该属性,它会隐藏它。如果您引用该对象作为它的基本元素,它仍将调用基本属性,而不是您的新属性。使用新的唯一方法是将其引用为新的。IE。

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
于 2012-09-19T16:17:30.840 回答