问题
I have a class that inherits from another class, who has a non-virtual property ("Controls").
Since I can't overwrite this property, Im using the 'new' keyword associated with my property.
At runtime, this property is called as I want it to, in the correct context.
When I open my form from the designer, the designer calls the base.Controls instead of my 'new' control.
Am I missing something, or is this just incorrect behavior in the winforms designer?
Edit, added the code in question for more explanation. I have the following class:
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;
}
}
}
When I get to the following code in my intializecomponent:
BauerGroupBox thisBox = new BauerGroupBox()
thisBox.Controls.Add(something)
When I add a new 'BauerGroupBox' to my code, it works fine. However, when I open my code in the designer (even while using the debugging the devenv), the messagebox is NOT shown, and the breakpoint is NOT hit.
When I run my app, the breakpoint is hit.
回答1:
You're missing something - what you're describing is correct behaviour.
The workaround is to re-populate your new Controls
property right after the call to InitializeComponent()
. Like so:
public MyForm() {
InitializeComponent();
this.Controls.AddRange( base.Controls );
}
However, why are you trying to "override" the Controls
property? What new, non-standard, behaviour are you after? I believe there is a better alternative.
回答2:
You misunderstand how the new keyword works. New doesn't override the property, it hides it. If you reference the object as it's base element, it will still call the base property, not your new one. The only way to use the new one is to reference it as the new one. 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
回答3:
I think I understand your situation, so let me explain what the designer is doing:
First, at runtime, you are effectively running an instance of your BauerGroupBox
control. (That said, it's also all likely that you are accessing the Controls
property through a reference of this derived type, namely BauerGroupBox
, and as @Mystere Man correctly argues, the member BauerGroupBox.Controls
hides the inherited member (wherever it is last defined) -- it does not override it.
Bur the issue in question is that at design-time, in the designer of the BauerGroupBox
control, you are NOT "running" an instance of BauerGroupBox
, instead you are designing
a prototype based on ComponentFactory.Krypton.Toolkit.KryptonGroupBox
and that is effectively the type of the control you are "running".
I repeat, the designer of BauerGroupBox
does not have an instance of BauerGroupBox
running, but an instance of ComponentFactory.Krypton.Toolkit.KryptonGroupBox
. No BauerGroupBox
exists in the designer, because, well.. you are designing it!!!
NOW, to add a bit more confusion to that (none really, it's all very simple if you think a bit about it,) you will see that if you go to any other designer of any other control, say a form, and then you drag and drop an instance of your BauerGroupBox
, and add some controls to it, you will your message box, and yes, in that case, just like in the "runtime" case, it means that you are effectively hosting a BauerGroupBox
... but in this case, you are not designing BauerGroupBox
.
As other @Dai mentioned, if what you're trying to do is to prevent people from adding controls to it, then you should follow other design plans: for example, override the
protected virtual Control.ControlCollection CreateControlsInstance();
method.
来源:https://stackoverflow.com/questions/12498565/c-sharp-winforms-designer-calling-base-property-instead-of-new-one