Announcement

Collapse
No announcement yet.

ListBox überladen --> Problem mit Designer

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • ListBox überladen --> Problem mit Designer

    Hey,

    hab da mal wieder ein kleines Problem und bräuchte da etwas Hilfestellung.

    Und zwar wollte ich mir eine eigene ListBox machen, welche sich beim initialisieren automatisch mit allen gefunden Seriellen Ports füllt.
    Dazu habe ich einfach den Konstruktor meiner vererbten List Box Klasse überladen.
    Code:
            public SerialPortSelectionBox()
            {
                string[] portNames = SerialPort.GetPortNames();
                this.Items.AddRange(portNames);
            }
    Das funktioniert soweit EIGENTLICH auch ganz gut. Mein Problem ist dass der Designer mir quas die Items nochmal selbst hinzufügt:

    Code aus dem Designer:
    Code:
    // 
                // serialPortSelectionBox1
                // 
                this.serialPortSelection1.Items.AddRange(new object[] {
                "COM1",
                "COM6",
                "COM4",
                "COM5",
                "COM3"});
    Ich kann diesen Teil zwar löschen, aber sobald ich die ListBox etwas verschiebe wird dieser Teil neu hinzugefügt.
    Kann ich das irgendwie abstellen, bzw verhindern dass der Designer die Box von selbst füllt?
    Gruß

    Tobias

  • #2
    Einfach im ganz normalen CodeBehind programmieren und nicht im Designer? Im Designer solltest Du eigentlich gar nichts ändern müssen.

    Zum Beispiel könntest Du im Konstruktor nach InitialiseComponents - wichtig danach, weil sonst alle Controls noch null sind - einfach die Items setzen.
    Ich würde für so etwas allerdings nicht ein CustomControl machen, sondern nur ein zusammengesetztes UserControl. Composition over Inheritance

    Comment


    • #3
      Hey,
      danke für die antwort!!
      Der Punkt ist, ich habe im Designer nicht(!) programmiert, den Inhalt den du in dem zweiten Abschnitt siehst ist rein vom Designer generiert...und genau das ist das Problem. Dadurch dass der Designer diesen Code quasi schon vorgeneriert und dann aber beim initialisieren der Konstruktor nochmal ausgeführt wird hab ich alle Elemente doppelt in meiner ListBox.

      Comment


      • #4
        Da hast du mehrere Möglichkeiten.

        a.) In deiner Methode die DesignMode Property abfragen um festzustellen ob deine ListBox gerade im Designer verwendet wird(und dann eben nicht an den Items rumspielen) .

        b.) In deiner Methode vor dem hinzufügen der Items die Items einfach mal leeren dann ist egal was da zur Designzeit drinsteht.

        c.) Oder auf fanderlf hören. Wenn in deiner Ableitung nicht mehr passiert als das Daten hinzugefügt werden ist das deutlich übertrieben. Würdest du ja auch nicht für jedes Label machen nur weil da ein anderer Text angezeigt wird, oder

        Comment


        • #5
          Hey,

          also okay Möglichkeit a) hat bei mir ( aber kann au sein das ichs falsch mach ) nicht geholfen --> Ich frage einfach direkt im Konstruktor ab

          Code:
          if (this.DesignMode)
                 return;
          Möglichkeit b) klingt einleuchtend aber hat keine Abhilfe geschaffen ( also ich hab einfach vor dem hinzufügen der Items im Konstruktor noch ein
          Code:
          this.Items.Clear()
          gesetzt.

          Und okay ihr habt recht, lediglich für das hinzufügen dieser Objekte ist es wirklich etwas übertrieben von daher kann ich in dem Fall auch ne ganz normale List Box benutzen. ( Habe nur vorher ne ComboBox überladen müssen weil die einige zusätzliche Funktionalitäten bieten musste, deshalb war ich da grad so drin ^^ )

          Aber, trotzdem würde mich für die Zukunft interessieren wie ich das Problem ( sollte es mal wieder auftreten ) umgehen könnte.
          Benutz ich die beiden anderen Lösungsansätze falsch?
          Gruß

          Tobias

          Comment


          • #6
            Ich denke ein CustomControl, also vererben und überschreiben bzw. komplett selber schreiben, würde ich nur machen wenn Du ein Control was brauchst was etwas am Verhalten ändert, was man nicht per Properties ändern kann. Ausserdem würde ich es evtl. noch überschreiben, wenn Du grob etwas an der Art und Weise wie das Control gezeichnet wird änderst.
            Generell würde ich solche Controls aber eher zusammensetzen, da diese ja meist relativ speziell sind (UserControl) oder aber einfach vom Parent befüllen lassen. Bei so kleinen Sachen wie dem von Dir gezeigten ist das ja gerade mal ein Aufruf gegen einen Datencontainer.

            Comment


            • #7
              Benutz ich die beiden anderen Lösungsansätze falsch?
              Vermutlich

              Der Kardinalfehler war zum befüllen mit Daten eine Ableitung zu missbrauchen. Der Sekundärfehler das auch noch im Constructor zu erledigen. Der läuft nun mal vor der Initialisierung des Form und sobald du an den Items im Designer rumspielst ist dein Code im Constructor eh Makulatur da durch den Code in der Form dieser voraussichtlich wieder über klatscht wird.

              a.) Wenn du schon einmal den vorherigen Code ausgeführt hast und noch die alten Daten im Designer siehst musst du die erst löschen. Die Lösung wird nur in Zukunft verhindern das die Items in den Designercode aufgenommen werden wenn da schon fälschlicherweise Items drinstehen verschwinden die nicht einfach.

              [Highlight=C#]public SerialPortSelectionBox()
              {
              if (!this.DesignMode)
              {
              string[] portNames = SerialPort.GetPortNames();
              this.Items.AddRange(portNames);
              }
              }[/Highlight]


              b.) Den Code im Constructor auszuführen ist dann tatsächlich zu früh. Weil logischerweise dein Control instanziiert wird und damit dein Constructor und dann der andere Code in der InitializeMethode. Der Code muss also nach dem Initialisieren auf der Form laufen also z.B in OnVisibleChanged des Controls.

              [Highlight=C#] protected override void OnVisibleChanged(EventArgs e)
              {
              base.OnVisibleChanged(e);

              if (Visible)
              {
              this.Items.Clear();
              this.Items.AddRange(SerialPort.GetPortNames());
              }
              }[/Highlight]

              Comment


              • #8
                Ha, okay ja jetzt funktionierts...aber ich denke ich werd auf euern Ratschlag hören und das Form einfach dann in der Form mit Daten füllen wie man es normal auch macht.

                Der Gedanke war nur ich hatte vorher eine ComboBox geschrieben bei der ich diverse Methoden überladen musste und da ich dann grad so schön dabei war dacht ich mach ich das bei der ListBox auch...auch wenn es sich im nachhinein als unnötig erweist.

                Auf jedenfall nochmal vielen dank für die nette Hilfe euch beiden!!!
                Gruß

                Tobias

                Comment

                Working...
                X