2016-05-19 11 views
-1

Ich habe eine Benutzersteuerung erstellt und ich brauche, dass, wenn die Eigenschaft Controls lesen wird ein Control von mir und nicht die Basiseigenschaft Control.ControlsWie kann ich eine Eigenschaft nur von der geerbten Klasse zugänglich machen?

Ich tat dies angegeben zurück und es funktioniert, wenn ich CustomGroupBox.Controls lesen, aber Wenn eine Methode, die ein Steuerelement als Parameter erhält (es erhält einen beliebigen Steuerelementtyp wie CustomGroupBox, Button, Panel usw.) versucht, Control.Controls zu lesen, erhält es die Basis-ControlCollection.

Lassen Sie mich mein Problem mit dem Code erklären

CustomGroupBox.cs

public partial class CustomGroupBox : UserControl 
{ 
    Panel Panel1 = null; 
    Panel Panel2 = null; 
    bool UseBaseControls = true; 

    public CustomGroupBox() 
    { 
     InitializeComponent(); 

     Panel1 = new Panel() { Name = "Panel1" }; 
     Panel2 = new Panel() { Name = "Panel2" }; 
     Controls.Add(Panel1); 
     Controls.Add(Panel2); 

     UseBaseControls = false; 
    } 

    public new ControlCollection Controls { get { return UseBaseControls ? base.Controls : Panel1.Controls; } } 
} 

Form1.cs

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     CustomGroupBox Container = new CustomGroupBox(); 
     Container.Controls.Add(new Button()); 
     Container.Controls.Add(new Button()); 
     Container.Controls.Add(new Button()); 
     Container.Controls.Add(new Button()); 

     Control Parameter = Container; 

     int i = Container.Controls.Count;    // i=4 
     int j = Parameter.Controls.Count;    // j=2 
    } 
} 

Hat jemand weiß, was muss ich auf CustomGroupBox.cs so j ändern = 4?

Update:

ich eine Lösung nicht finden kann, habe ich versucht, eine interfaz wie IContainerControl zu implementieren, aber es does 't Arbeit.

+1

Gewöhnen Sie sich an, Ihre Einheimischen mit kleinen Buchstaben zu benennen. Das ist der Standard in C#. Benennen Sie Eigenschaften und Felder sowie Methoden und Typen, die mit großen Buchstaben beginnen. –

+0

So funktioniert 'neu': Was genau ist Ihr Ziel? Vielleicht gibt es einen anderen Weg. – Blorgbeard

+0

Das ist wahr Eric – joe

Antwort

1

Nun, das Hauptproblem hier ist, dass die UserControl.Controls -Eigenschaft nicht virtuell ist und daher nicht in Ihrer abgeleiteten Klasse CustomGroupBox überschrieben werden kann. Mit anderen Worten, es gibt keinen Vtable-Eintrag für den Getter dieser Eigenschaft.

Somit kann jeder Code, der die Objektinstanz als eine der Basisklasse-Typen (UserControl, Control usw.) und ruft die Controls Eigenschaft von der Basisklasse erhalten Ergebnisse wahrnimmt.

Verwendung des new Begriff hier hat man effektiv aktiviert ist, eine ganz neue Eigenschaft Controls zum CustomGroupBox Klasse aufgerufen hinzuzufügen, aber das neue Eigenschaft ist tatsächlich unterscheidet sich von der Eigenschaft des gleichen Namens in den Basisklassen. Sie können den Getter Ihrer neuen Eigenschaft dann nur über eine Variable aufrufen, die stark als CustomGroupBox eingegeben ist.

Eine Technik würde Ihre Parameter Variable in Form1_Load zu einer CustomGroupBox "upcast", aber das ist möglicherweise nicht immer eine Option für Sie in komplexeren Szenarien.

könnten Sie schreiben Code wie:

Control Parameter = Container; 

int j = ((Parameter as CustomGroupBox)?.Controls ?? Parameter.Controls).Count; 

Dieser Code ein sicheres upcast von Typ vor Control-CustomGroupBox würde versuchen, die Controls Eigenschaft Getter aufgerufen wird und zurück auf die Basisklasse Controls Eigenschaft Getter fallen, wenn Parameter nicht wirklich ist a CustomGroupBox.

+1

Thx @kkahl, in der Tat habe ich festgestellt, dass ich 'Parameter' als' CustomGroupBox' wirken kann, aber wie Sie sagen, es ist nicht immer eine Option. Wenn ich zum Beispiel "CustomGroupBox" in einer DLL kompiliere und ein anderer Entwickler mein Benutzersteuerelement verwendet und es an eine Drittanbieter-DLL (Control Bar) weitergibt, wird dll die gewünschte ControlCollection nicht erhalten. – joe

Verwandte Themen