TabPage ControlCollection sortieren

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von mrMo.

    TabPage ControlCollection sortieren

    Hallo,

    ich habe mal wieder ein kleines Problem.
    Mein Projekt hat ein TabControl mit mehreren TabPages.
    Alles was auf den TabPages an Einstellungen gemacht wird, wird in einer XML-Datei gespeichert.
    Dazu durchläuft das Programm das TabControl -> TabPage-weise und auf jeder TabPage werden alle Controls der ControlCollection durchlaufen und die zu speichernden Informationen in die XML-Datei geschrieben.
    Das funktioniert alles wunderbar. Die XML-Datei ist sauber nach TabPages sortiert.
    Auch das anschließende Laden der XML-Datei und füllen der Controls mit den daraus gelesenen Informationen.
    Mein Problem ist nun, dass es eine TabPage gibt, auf der ein ganz bestimmtes Control am Anfang der XML-Auflistung dieser TabPage stehen muss.
    Dies aus dem Grund, weil der Wert dieses Controls definiert, welches UserControl auf der TabPage zu finden ist.
    Dieses muss dann zunächst geladen werden, bevor die nächsten XML Infos geladen und in das UserControl eingetragen werden.
    Meine Idee war es nun, die ControlCollection der TabPage vor dem Speichern zu sortieren und zwar so, dass das entscheidende Control am Anfang der Liste steht.
    Ich habe zum Sortieren der Liste auch was gefunden.
    Hat ein bisschen gedauert bis ich den LINQ Ausdruck verstand habe.
    Das sortiert zwar erst mal nach den Koordinaten der Controls, aber das lässt sich ja ändern.
    Mein Problem ist, wie bekomme ich die dann sortierte Liste an die Stelle der original ControlCollection?
    Das bekomme ich irgendwie nicht hin.

    VB.NET-Quellcode

    1. For Each ctrl As Control In frmActiveForm.Controls 'das Form nach Controls durchsuchen
    2. If TypeOf ctrl Is TabControl Then 'ist Control ein TabControl
    3. For Each TabPage As Control In ctrl.Controls 'TabPage nach Sub-Controls durchsuchen
    4. If TabPage.Name = "tabpg_SPIHubCH1" Then
    5. Dim sortedControls As List(Of Control)
    6. sortedControls = TabPage.Controls.Cast(Of Control).OrderBy(Function(c) c.Location.X).OrderBy(Function(c) c.Location.Y).ToList()
    7. 'jetzt habe ich eine sortierte Liste in sortedControls, wie weise ich diese der ControlCollection der TabPage zu?
    8. End If
    9. ... 'hier werden dann die Daten in die XML-Datei geschrieben
    10. Next
    11. End If
    12. Next

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „roepke“ ()

    Wenn man das Ganze objektorientiert per DataBinding und Serialisierung löst, wäre das ganze deutlich eleganter.

    Klasse schreiben mit allen Propertys
    Propertys an das jeweilige Control binden
    Klasse bzw. Objekt serialisieren/deserialisieren
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen

    roepke schrieb:

    VB.NET-Quellcode

    1. sortedControls = TabPage.Controls.Cast(Of Control).OrderBy(Function(c) c.Location.X).OrderBy(Function(c) c.Location.Y).ToList()
    2. 'jetzt habe ich eine sortierte Liste in sortedControls, wie weise ich diese der ControlCollection der TabPage zu?
    Die Frage ergibt keinen Sinn.
    Du liest da die Controls aus der ControlCollection aus - und willst sie derselben ControlCollection wieder zuweisen? Aber da sind sie doch schon drin!
    Die Frage enthält 2 Sinn-Fehler:
    1. einer ControlCollection kannste nix zuweisen - Die Property ist ja Readonly.
      Allenfalls etwas hinzufügen kannste ihr - nämlich Controls
    2. Falls zu zufügen meinst statt zuweisen - wie gesagt: Die Controls sind bereits zugefügt - die kannste nicht ein zweites Mal zufügen.
    Was also willst du wirklich tun?
    @ErfinderDesRades Mag ja sein, dass die Frage in deinen Augen/Ohren keinen Sinn ergibt, ich habe mich vielleicht nicht ganz klar ausgedrückt. OK, wenn ControlCollection ReadOnly ist (wußte ich nicht, hab's aber befürchtet), dann frage ich mich, wie ich der ControlCollection weitere Controls hinzufügen kann? Weil ich doch sehr wohl in der Lage bin das zur Laufzeit zu tun. Wo werden den diese Art von Controls verwaltet? Gibt dafür eine eigene Collection?
    Um zu meiner eigentlichen Frage zurück zu kommen: ich möchte diese ControlCollection sortieren. Ob ich sie dazu lesen - sortieren - und dann die "alte" durch die sortierte ersetzen kann oder ob das evtl. sogar direkt ohne den Umweg einer weiteren Liste geht, das ist meine eigentliche Frage. Ziel ist, dass ein ganz bestimmtes Control in der ControlCollection am Ende ganz am Anfang der ControlCollection steht. Ich also beim lesen der ControlCollection diese Control als erstes lese. Und nein, ich will es nicht in der ControlCollection suchen, ich hätte es gerne am Anfang der Liste. Dass ich dazu sehr wohl einmal suchen muss, weil ich ja die Liste entsprechend sortiert haben will ist mir schon klar, nur im Anschluss soll es halt als erstes darin stehen.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „roepke“ ()

    roepke schrieb:

    wenn ControlCollection ReadOnly ist (wußte ich nicht, hab's aber befürchtet), dann frage ich mich, wie ich der ControlCollection weitere Controls hinzufügen kann?
    Da hab ich mich nicht korrekt ausgedrückt:
    Die Property TabControl.Controls, vom Typ ControlCollection - die ist Readonly.
    Das heisst, sowas ist nicht zulässig:

    VB.NET-Quellcode

    1. myTabControl.Controls = new ControlCollection() ' unzulässige Zuweisung, da Readonly

    Es heisst natürlich nicht, dass man einer ControlCollection kein Control hinzufügen kann. Das Zufügen geht wie bei jeder Collection mit der .Add()-Methode.
    Beachte, dass Zufügen etwas anderes ist als Zuweisen.
    Zuweisen: a = b
    Zufügen: c_Collection.Add(c)

    roepke schrieb:

    Ziel ist, dass ein ganz bestimmtes Control in der ControlCollection am Ende ganz am Anfang der ControlCollection steht.
    Schau dir im Objectbrowser dieses mal an:

    Objectbrowser schrieb:

    Public Overridable Sub SetChildIndex(child As System.Windows.Forms.Control, newIndex As Integer)
    Member of System.Windows.Forms.Control.ControlCollection


    Summary:
    Sets the index of the specified child control in the collection to the specified index value.

    Parameters:
    child: The childSystem.Windows.Forms.Control to search for.
    newIndex: The new index value of the control.
    (Tatsächlich hättest du das auch selber finden können, wenn du den Objectbrowser benutzen tätest)
    @ErfinderDesRades Danke für das Feedback. Den ObjectBrowser übersehe ich immer. Ich suche eher im WWW mit einer (nach Möglichkeit) gezielten Problemstellung.
    'SetChildIndex' hat mir gut geholfen. Allerdings gehe ich gerade (vermutlich) den etwas umständlichen Weg, erst eine LIste zu sortieren und anschließend die Indizes der ControlCollection zu ändern.

    VB.NET-Quellcode

    1. For i As Integer = 0 To sortedControls.Count - 1
    2. For Each c As Control In ctrlTabPage.Controls
    3. If sortedControls(i) Is c Then
    4. ctrlTabPage.Controls.SetChildIndex(c, i)
    5. Exit For
    6. End If
    7. Next
    8. Next

    Funktioniert, aber evtl. geht das Ganze ja auch direkt ohne die zusätzliche Liste. Hab ich aber bisher noch nicht hin bekommen.
    Weiß nicht ob mein Vorschlag dein Problem löst. Hab den Thread nicht mehr weiter verfolgt. Am Ende ging es wohl um irgendwelche sortierereien, damit hat mein Vorschlag nichts zu tun. Wie dem auch sein, für YT Tutorials bin ich nicht zu haben.
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen