List Of Controls

  • VB.NET

Es gibt 14 Antworten in diesem Thema. Der letzte Beitrag () ist von DragsTrail.

    List Of Controls

    Hallo.

    Ich hab ein Panel wo ich per DragDrop PictureBoxes rein schiebe und diese in Y, also untereinander anordne. Per Button speichere ich alle Panel.Controls in eine List of Control, damit ich diese später wieder laden kann.

    Mein Problem ist, das sich diese List of Controls irgendwie automatisch mit den Panel.Controls updated???????? ?( ?( ?( ?( ?(

    Kann man das irgendwie unterbinden???

    Danke

    Schöne Grüße
    Nee, ich kapier's auch beim 3. mal lesen nicht.

    DragsTrail schrieb:

    Per Button speichere ich alle Panel.Controls in eine List of Control, damit ich diese später wieder laden kann.
    Wie ist denn da der Code?

    DragsTrail schrieb:

    das sich diese List of Controls irgendwie automatisch mit den Panel.Controls updated
    D.h. Du brauchst gar nicht mehr auf [Speichern] zu klicken und es wird trotzdem gespeichert oder wie? Tja, wie geschrieben, ich blick's leider nicht.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    vielleicht magst du uns deinen Code der betroffenen Stellen zeigen? Weil deine Beschreibung hört sich etwas dubios an. Glaube z.B. nicht das sich deine List( Of T) einfach so automatisch updatet, ohne das du diesebzüglich etwas unternommen hast...
    "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
    Naja, da Control eine Klasse und somit ein Referenztyp ist, ändert sich bei der Änderung eines Controls auch das Äquivalent in der Liste. Also falls ich deine Frage überhaupt richtig verstanden habe. Unterbinden könntest du das, indem du keine direkte Zuweisung verwendest, sondern die Controls klonst.

    @ Pascalony

    Die Posts haben sich überschnitten. Das macht Sinn. Das gleiche Problem hatte ich mal beim GDI+ mit der Matrix. DIese musste ich auch Clonen.

    Kannst du mir bitte sagen wie ich ein Control richtig Clone? Danke

    ##############################################################################

    Ja die Fragestellung ist schon dubios. Stimmt. War ein sehr langer Tag. :D

    Das Problem im Detail: Im Panel1 ziehe ich 3 Pictureboxs rein, die sich untereinander anordnen!
    =============
    Pic1
    Pic2
    Pic3
    =============
    Jetzt Button 1 und in die Lst Speichern.

    VB.NET-Quellcode

    1. Dim Lst As New List(Of Control)
    2. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    3. For Each c As Control In Panel1.Controls
    4. Lst.Add(c)
    5. Next
    6. End Sub


    Wenn ich jetzt eine Pic4 zwischen Pic2 und Pic3 positioniere, passt es noch
    =============
    PIc1
    Pic2
    Pic4
    Pic3
    =============

    Nach dem ich jetzt den Button2 klicke ( Code weiter unten ) kommt das raus:
    =============
    Pic1
    Pic2

    Pic3
    ============
    Da wo Pic4 war, aber nicht abgespeichert ist ist ein leerer Platz.

    VB.NET-Quellcode

    1. Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    2. Panel1.Controls.Clear()
    3. For Each c As Control In Lst
    4. Panel1.Controls.Add(c)
    5. Next
    6. End Sub

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

    DragsTrail schrieb:

    Wenn ich jetzt eine Pic4 zwischen Pic2 und Pic3 positioniere
    Was meinst Du mit Positionieren? X-Y-Platzierung auf dem Panel?

    DragsTrail schrieb:

    Da wo Pic4 war, aber nicht abgespeichert ist ist ein leerer Platz..
    Gleiche Frage.

    Hat sich. Y-Auflistung. Hast Du ja geschrieben. Dann stellt sich die Frage, mit welchem Code Du die Controls platzierst? Denn in nem Panel gibt es standardmäßig keine Platzierungsordnung. Wenn ich einem Panel Controls hinzufüge, sind die dort, wo sie im ParentControl vorher waren. Wenn die PicBoxen frisch per Neww erstellt wurden, muss man ja explizit Koordinaten mitgeben. Was liegt vor?

    Gegenvorschlag: FloatLayoutPanel.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Ich ziehe mit der Maus die PicBox auf das Panel. X bleibt immer gleich. Y wird immer um 100 erhöht.

    Im DragDrop:
    * Überprüfe ich ob ein Control unter der Maus ist
    * Wenn nicht, Y +=100 und einfügen
    * Wenn ja, verschiebe ich das Control unter der Maus und alle darunterliegenden ( fals vorhanden ) um Y100 und füge auf der aktuellen Position das Pic ein.

    Das passt auch. Es wird alles richtig dargestellt und positioniert.

    Wie oben schon erklärt:

    Ich ziehe 3 Pics rein die sich untereinander sortieren.

    Pic1 Y10
    Pic2 Y110
    Pic3 Y210

    Mit Button1 speichere ich die Controls in der Lst ab.

    Jetzt Pic4 zwischen Pic2 und Pic3. Im Panel1.Control kannst du ja die Control.Top auslesen, die dann so ( richtig ) ist:

    Pic1 Y10
    Pic2 Y110
    Pic4 Y210
    Pic3 Y310

    Jetzt Buitton2: Alle Controls im Panel löschen und aus der lst einfügen. Wenn ich jetzt die Control.Top aus dem Panel1.Control auslese ist es ( falsch ) so:

    Pic1 Y10
    Pic2 Y110
    Pic3 Y310

    Diese lst ( List of Control ) ist nur im Button1 und Button2 drin, SONNST NIRGENDWO. Und trotzdem passiert da etwas.
    Dann würde ich mal bei Deinem Einfügecode bei paar Haltepunkte setzen und die Bedingungen vergleichen. Denn irgendeine der dann im Code auftauchenden Bedingungen scheint ja wohl anders zu sein als Du erwartest. notfalls mit Zusatzüberwachungsvariablen und Codeüberwachung arbeiten. Alles andere wäre nur Spekulatiusbacken.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Ich verstehe viele Formulierungen des TE nicht, aber auch ungründlich gelesen. Nur soviel:

    DragsTrail schrieb:

    Kannst du mir bitte sagen wie ich ein Control richtig Clone?
    Das geht nicht.

    VB.NET-Quellcode

    1. Dim Lst As New List(Of Control)
    2. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    3. For Each c As Control In Panel1.Controls
    4. Lst.Add(c)
    5. Next
    6. End Sub
    7. Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    8. Panel1.Controls.Clear()
    9. For Each c As Control In Lst
    10. Panel1.Controls.Add(c)
    11. Next
    12. End Sub
    Was soll das?
    Bei Button1 schiebste Referenzen der Panel1-Controls nach Lst, und bei Button2 entfernste alle Panel1-Controls, und packst sie wieder drauf - versuchste zumindest - aus Lst.

    Wichtiger Hinweis: ControlCollection (etwa Panel1.Controls) verhält sich eigenartig. Verzichte auf Panel1.Controls.Clear(). Wird ein Control auf ein anneres geschoben, so entfernt es sich selbst aus seiner vorherigen ControlCollection.
    Hab ich schon zich mal getestet.

    Sobald die Pic4 in Panel1.Control drin ist, wird in der lst die Pic3 um Y100 verschoben. Im gleichen Augenblick.

    Ich hab das Problem jetzt über Umwege gelöst sprich ich merke was verschoben wurde und wenn nicht gespeichert wird, dann wird dass was verschoben wurde wieder zurückgeschoben in der lst. :D OMG

    Es würde mich aber trotzdem interessieren warum das so ist und wie man es genau verhindern kann.

    ErfinderDesRades schrieb:

    Das geht nicht.


    Naja er könnte sich selbst ne Methode zum clonen schreiben. Er wird wohl eh nur ein paar Properties verwenden, und dann erstellt er eben ein Control mit den gewünschten Properties und gibt das zurück. Dachte da an sowas:
    stackoverflow.com/questions/10…-controls-c-sharp-winform

    @DragsTrail Noch mal explizit, was der @ErfinderDesRades schrieb:
    Wenn Du ein Control einer schnöden List(Of Control) zuweist, isses sowohl in der List als auch in der MyControl.Controls-List vorhanden.
    Wenn Du ein Control aus einer MyControl.Controls-List einer anderen MyControl2.Controls-List zuweist, ist es aus der MyControl.Controls-List verschwunden, denn ein Control kann nur ein Parent haben.
    Wenn Du ein Control aus der schnöden List(Of Control) einer MyControl.Controls-List zuweist, in der es bereits vorhanden ist, passiert nix weiter.
    Wenn ein Control nur noch in der schnöden List(Of Control) vorhanden ist, hängt es in der Luft und erzeugt ggf. ein Memory Leak (z.B. PictureBox mit ner Bitmap drinne).
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany

    Könnte man dann eben nicht die Kopie verwenden? Hier ein Beispiel, was bei mir funktioniert:

    C#-Quellcode

    1. public partial class Form1 : Form
    2. {
    3. public Form1()
    4. {
    5. InitializeComponent();
    6. }
    7. List<Control> controls;
    8. private void Form1_Load(object sender, EventArgs e)
    9. {
    10. controls = new List<Control>();
    11. foreach (Control control in panel1.Controls)
    12. controls.Add(Clone<Control>(control));
    13. foreach (Control control in panel1.Controls)
    14. control.Location = new Point(200, 200); //Position des Controls im Panel wird verändert
    15. MessageBox.Show($"{controls[0].Location}"); //Position wird erhalten
    16. }
    17. public static T Clone<T>(T controlToClone)
    18. where T : Control
    19. {
    20. PropertyInfo[] controlProperties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
    21. T instance = Activator.CreateInstance<T>();
    22. foreach (PropertyInfo propInfo in controlProperties)
    23. {
    24. if (propInfo.CanWrite)
    25. {
    26. if ((propInfo.Name == "Location") || (propInfo.Name == "Size")) //hier gewünschte Eigenschaften filtern
    27. propInfo.SetValue(instance, propInfo.GetValue(controlToClone, null), null);
    28. }
    29. }
    30. return instance;
    31. }
    32. }

    Pascalony schrieb:

    Könnte man dann eben nicht die Kopie verwenden?
    Das wäre dann ein neues Control mit selbem Namen.
    Darüber müsste @DragsTrail befinden.
    =============

    RodFromGermany schrieb:

    Wenn Du ein Control aus der schnöden List(Of Control) einer MyControl.Controls-List zuweist, in der es bereits vorhanden ist, passiert nix weiter.
    Ich hab das noch mal getestet, weil ich zunächst vermutete, dass da eine ControlBereitsVorhandenException kommt, aber es passiert wirklich nix:

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. Label1.Text = Me.Controls.Count.ToString
    3. Me.Controls.Add(Me.Button1)
    4. Label2.Text = Me.Controls.Count.ToString
    5. End Sub
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Erst mal vielen Dank an alle für die Unterstützung.

    @ErfinderDesRades Button1 und 2 war nur symbolisch um das Problem besser zu sehen.

    @RodFromGermany Super erklärt. Vielen Dank.

    @Pascalony Der Ansatz war Mega. Der "Fast CLone" :D erfährt keine Veränderung in der List of Control, egal was ich im Panel anstelle. Genau das hab ich gebraucht. Vielen vielen Dank.