Laden...

Control Collection als Navigation

Erstellt von Duesmannr vor 6 Jahren Letzter Beitrag vor 6 Jahren 2.599 Views
D
Duesmannr Themenstarter:in
161 Beiträge seit 2017
vor 6 Jahren
Control Collection als Navigation

Hallo,

ich will auf meine UI eine andere Navigation haben. Ich habe dafür ein Panel was über die gesamte Breite geht. Ich habe zwei Klassen erstellt, einmal die Liste die die Controls verarbeitet und eine Controls Klasse, die ich erstellt habe um zwei weitere Properties für jedes Control zu haben, was in diese Liste kommen soll.

In dieses Panel adde ich Controls hinzu und die Größe der Controls wird anhand des Panels errechnet, hier ein Codeschnipsel:


public class ControlList : List<System.Windows.Forms.Control>
{
        /// <summary>
        /// In which panel the list is displayed
        /// </summary>
        public Panel DestinationPanel { get; }

        public ControlList(Panel destinationPanel)
        {
            this.DestinationPanel = destinationPanel;
        }

        public new void Add(System.Windows.Forms.Control control)
        {
            base.Add(control);
            this.DestinationPanel.Controls.Add(control);
            this.ChangeSize(); //Ändert die Größe von allen vorhanden Controls
        }
}

Und hier einmal die Control Klasse


public class Control
{
        public double Factor { get; set; }
        public bool Selected { get; set; }

        //Hier die Control Property, damit ich darauf von außen drauf zugreifen kann
        public System.Windows.Forms.Control SourceControl { get; set; }

        /// <summary>
        /// Override the mouse enter event from the source control
        /// </summary>
        public event EventHandler MouseEnter;

        private void AddEventsToControl()
        {
            this.SourceControl.MouseEnter += SourceControl_MouseEnter;
        }

        private void SourceControl_MouseEnter(object sender, EventArgs e)
        {
            this.MouseEnter?.Invoke(this, e);
        }
}

Das ganze funktioniert auch. Ich kann in meiner Liste auch die weiteren Properties zugreifen. Nur finde ich das ganze sehr unschön.

In der Control Klasse habe ich das Event, damit ich als object sender diese Control Klasse habe und nicht nur das SourceControl.

Ich will in dieser Liste, Labels, Textboxen, Panels etc. hinzufügen können. Aber ich bekomme es zurzeit nicht besser hin.

Habt Ihr Anregungen, Verbesserungen?

Mit freundlichen Grüßen

W
196 Beiträge seit 2008
vor 6 Jahren

Verstehe ich richtig, dass Dein Problem ist, dass Du nicht genau weißt, wie Du statt Deiner 'Control'-Klasse Labels etc. hinzufügst, weil Dir nicht klar ist, wie Du Deine zusätzlichen Properties in diese Label etc. bekommst?

Da gibt es mehrere Ansätze: du könntest Ableitungen der Standard-Controls (Label etc.) erstellen und diese abgeleiteten Klassen verwenden oder die Tag-Eigenschaft der Standardklassen für Deine zusätzlichen Informationen nutzen...

Falls es darum nicht geht, spezifiziere bitte 'finde das ganze sehr unschön'...

D
Duesmannr Themenstarter:in
161 Beiträge seit 2017
vor 6 Jahren

Ich könnte jedes Control ableiten lassen was ich brauche und die zwei Properties hinzufügen.

Aber ich will nur eine Klasse die die zwei Properties hat und ich mit dieser Klasse jedes Control "darstellen" kann.

Am liebsten würde ich z.B.


Control newControl = new Label();

sodass "newControl" ein Label ist, aber die zwei Properties hat.

Hatte erst an Generic gedacht, aber das bringt mich auch nicht weiter.

Hoffe das ist verständlicher.

Mit freundlichen Grüßen

W
196 Beiträge seit 2008
vor 6 Jahren

Dann nutze die TAG-Eigenschaft der Controls. Dort kannst Du ein Objekt einer Klasse ablegen, die Deine zusätzlichen Eigenschaftenn implementiert...

public class AdvControlProperties
{
        public double Factor { get; set; }
        public bool Selected { get; set; }
}
...
Control newControl = new Label() { Tag = new AdvControlProperties() };

D
Duesmannr Themenstarter:in
161 Beiträge seit 2017
vor 6 Jahren

Das sieht gut aus. Kannte die Property nicht.

Wenn ich dann das Label deklariert habe mit der AdvControlProperties Klasse, kann ich dann nur auf die Properties der Klasse mit


AdvControlProperties properties = newControl.Tag as AdvControlProperties;

double factor = properties.Factor;

zugreifen? Oder gibt es eine kürzere Variante?

4.939 Beiträge seit 2008
vor 6 Jahren

Du kannst dir dafür dann eine Erweiterungsmethode (extension method) erstellen:


double GetControlFactor(this control)
{
    AdvControlProperties properties = control.Tag as AdvControlProperties;

    return properties?.Factor;
}

Aufruf dann einfach per:


double factor = newControl.GetControlFactor();

D
Duesmannr Themenstarter:in
161 Beiträge seit 2017
vor 6 Jahren

@Th69
danke mit einer Extension Method funktioniert es.

Deklaration:


ControlList list = new ControlList(destinationPanel)
{
     Control label1 = new Label()
     {
          Text = "LabelText",
          Tag = new AdvControlProperties()
     },
     Control textbox1 = new TextBox()
     {
          Visible = false,
          Tag = new AdvControlProperties()
     }
};

Eine Frage bleibt mir aber noch.
Jetzt habe ich in dieser Liste zwei Controls.
Kann ich irgendwie herausfinden welches Control das eig. ist?

4.939 Beiträge seit 2008
vor 6 Jahren

z.B. den Typ mittels


control.GetType()

oder direkt per Cast:


Label label = control as Label;
if (label != null)
{
    // label.
}

D
Duesmannr Themenstarter:in
161 Beiträge seit 2017
vor 6 Jahren

z.B. den Typ mittels

  
control.GetType()  
  

Das sollte funktionieren und somit habe ich keine Fragen mehr.

oder direkt per Cast:

  
Label label = control as Label;  
if (label != null)  
{  
    // label.  
}  
  

Das würde nicht funktionieren, wenn ich noch Panels etc. drin habe, aber ich nicht weiß, welches Item was ist.

Ich bedanke mich für Eure Hilfe.

4.939 Beiträge seit 2008
vor 6 Jahren

Für ein Panel würdest du dann den entsprechend abgeänderten Code noch mal darunter (oder darüber) schreiben (also quasi wie ein if/else-Konstrukt).

D
Duesmannr Themenstarter:in
161 Beiträge seit 2017
vor 6 Jahren

Das stimmt, aber das Konstrukt wäre sehr lang, wenn ich 10 verschiedene Controls darin hätte.

D
Duesmannr Themenstarter:in
161 Beiträge seit 2017
vor 6 Jahren

Damit ich auf die verschiedenen Properties von den Controls drauf zugreifen kann.
Beispielsweise hat das Label Control die Property "TextAlign". Die eine Textbox
nicht hat.

4.939 Beiträge seit 2008
vor 6 Jahren

Aber dann mußt du doch casten, um auf die speziellen Eigenschaften der verschiedenen Controls zugreifen zu können?

D
Duesmannr Themenstarter:in
161 Beiträge seit 2017
vor 6 Jahren

Mit


control.GetType()

funktioniert es auch, ohne zu wissen, welches Control es eig. ist.