Laden...

Bewegliche Pictureboxen in Panel halten

Erstellt von falsecode vor 10 Jahren Letzter Beitrag vor 10 Jahren 3.217 Views
F
falsecode Themenstarter:in
55 Beiträge seit 2013
vor 10 Jahren
Bewegliche Pictureboxen in Panel halten

Hallo Community,
ich habe ein Problem mit pictureboxen welche ich nach einem klick auf ein picturebox erstelle. Diese Pictureboxen sind im Normalfall beweckbar,
sie werden links oben in meiner WinForm gedroppt und können von da aus über das komplette Fenster geschoben werden.
Ich habe dazu den folgenden Code geschrieben:

private void pictureBox1_Click(object sender, EventArgs e)
        {
            int i = 0;
            i++;

            if (i == 1) // erstelle picturebox
            {
                startpb = (Control)sender;
                PictureBox box = new PictureBox();
                box.Image = IP_Array_Grafik.Properties.Resources.PC;
                box.Width = 79;
                box.Height = 74;
                box.Name = "new_" + startpb.Name;
                box.TabStop = false;
                box.MouseDown += new System.Windows.Forms.MouseEventHandler(this.pictureBox_MouseDown);
                box.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pictureBox_MouseMove);
                box.MouseUp += new System.Windows.Forms.MouseEventHandler(this.pictureBox_MouseUp);
                box.MouseClick += new System.Windows.Forms.MouseEventHandler(this.pictureBox_MouseClickR);
                Controls.Add(box);
                

Mein Problem entsteht dann wenn ich versuche die gedroppten pictureboxen in ein Panel zu sperren.
Die box sitzt oben links in der Ecke des Panels, lässt sich dann aber nicht mehr bewegen.
Meine Code Anpassung dazu ist wie folgt:

private void pictureBox1_Click(object sender, EventArgs e)
        {
            int i = 0;
            i++;

            if (i == 1) // erstelle picturebox
            {
                startpb = (Control)sender;
                PictureBox box = new PictureBox();
                box.Image = IP_Array_Grafik.Properties.Resources.PC;
                box.Width = 79;
                box.Height = 74;
                box.Name = "new_" + startpb.Name;
                box.Parent = ObjektPanel;
                box.TabStop = false;
                box.MouseDown += new System.Windows.Forms.MouseEventHandler(this.pictureBox_MouseDown);
                box.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pictureBox_MouseMove);
                box.MouseUp += new System.Windows.Forms.MouseEventHandler(this.pictureBox_MouseUp);
                box.MouseClick += new System.Windows.Forms.MouseEventHandler(this.pictureBox_MouseClickR);
                Controls.Add(box);
                ########box.Parent = ObjektPanel;############
                ########ObjektPanel.Controls.Add(box);#########
                

Ich weiss leider nicht was ich einstellen könnte um das zu verhindern,
vielleicht könnt Ihr mir ja helfen.

liebe grüße
falsecode

771 Beiträge seit 2009
vor 10 Jahren

Hi,

deine letzte Zeile (Controls.Add) überschreibt wieder den Parent, d.h. entweder die letzte Zeile löschen oder aber stattdessen


ObjektPanel.Controls.Add(box);

Und die Eventzuweisung(en) kannst du auf


box.MouseDown += pictureBox_MouseDown;

kürzen.

49.485 Beiträge seit 2005
vor 10 Jahren

Hallo falsecode,

deine letzte Zeile (Controls.Add) überschreibt wieder den Parent

allerdings nicht mit einem anderen Parent, sondern einfach nochmal mit demselben Parent. Mir anderen Worten, die Zeilen

child.Parent = parent;

und

parent.Controls.Add (child)

machen beide das gleiche. Man könnte theoretisch auch beides machen, braucht aber nur eins von beiden und sollte sich für eins von beidem entscheiden, um die Russen nicht zu verwirren.

Aus dem gleichen Grund sollte man die Zeile Controls.Add(box); weglassen, denn ihre Wirkung wird durch die folgende(n) Zeile(n) danach gleich wieder aufgehoben.

Das sind aber Grundlagen und das sollten wir nicht diskutieren müssen, siehe [Hinweis] Wie poste ich richtig? Punkt 1.1.1.

herbivore

F
falsecode Themenstarter:in
55 Beiträge seit 2013
vor 10 Jahren

Wenn ich euch richtig verstanden habe, sollte mit dieser Anpassung der Code funktionieren. Doch das tut er leider nicht, das Problem das ich hatte das sich meine PictureBox oben links im Panel festsetzt und nicht mehr zu bewegen ist bleibt nach wie vor.

Aktueller Code:

private void pictureBox1_Click(object sender, EventArgs e) 
    {
                startpb = (Control)sender; 
                PictureBox box = new PictureBox(); 
                box.Image = IP_Array_Grafik.Properties.Resources.PC; 
                box.Width = 79; 
                box.Height = 74;
                box.Name = "new_pc_" + startpb.Name; 
                box.Parent = ObjektPanel; 
                box.Size = startpb.Size; L/box.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
                box.TabStop = false; 
                box.MouseDown += new System.Windows.Forms.MouseEventHandler(this.pictureBox_MouseDown); 
                box.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pictureBox_MouseMove);
                box.MouseUp += new System.Windows.Forms.MouseEventHandler(this.pictureBox_MouseUp);
                box.MouseClick += new System.Windows.Forms.MouseEventHandler(this.pictureBox_MouseClickR);
                box.MouseClick += new System.Windows.Forms.MouseEventHandler(this.pictureBox_MouseClickM);
ObjektPanel.Controls.Add(box);

Zu der Frage finde ich keine Antwort, Ihr vielleicht?

liebe grüße
falsecode

F
falsecode Themenstarter:in
55 Beiträge seit 2013
vor 10 Jahren

Hallo,
das ganze sieht wie folgt aus:

private void pictureBox_MouseDown(object sender, MouseEventArgs e) /* Wird aktiviert wenn sich der Mauszeiger über der Komponete
                                                                     befindet und eine Maustaste gedrückt wird. */
    {
        startpb = (Control)sender;
        if (startpb.Name.Contains("new_")) /* Wenn ein neuer visueller Komponent im Namen "new_"
                                               trägt werden Anweisungen ausgeführt. */
            {
                moving = true; // setzt die bool variable moving auf true.
                startLocation = e.Location; // setzt die Startlocation mit der gegebenen location gleich.
            }
    }

private void pictureBox_MouseMove(object sender, MouseEventArgs e) // Wird aktiviert wenn der Mauszeiger über die Komponete bewegt wird.
                                                                    
    {
        if (moving == true /* ursprünglich if(moving)*/) // Wenn bool moving gleich true ist 
            {
                startpb.Left += e.Location.X - startLocation.X; /* Nimmt den Abstand des visuellen Komponenten zur linken und zieht 
                                                                  die Startposition von der aktuellen Position ab, das ganze in der X-Koordinate. */
                startpb.Top += e.Location.Y - startLocation.Y; /* Nimmt den Abstand des visuellen Komponenten zur rechten und zieht 
                                                                  die Startposition von der aktuellen Position ab, das ganze in der Y-Koordinate. */
            }
     }

private void pictureBox_MouseUp(object sender, MouseEventArgs e) /* Wird aktiviert wenn sich der Mauszeiger über der Komponete
                                                                     befindet und eine Maustaste losgelassen wird. */
    {
        moving = false; // Beim loslassen der Maus bool moving auf false und damit MouseMove deaktiviert.
    }

private void pictureBox_MouseClickR(object sender, MouseEventArgs e) // Wird aktiviert beim Klick auf die Box.
    {
        if (e.Button == MouseButtons.Right) // Vergleicht den gedrückten Button mit den rechten Mausklick, wenn zutreffend, Ausführung ausüben.
            {
                Controls.Remove((Control)sender);  // Entfernt das visuelle Steuerelement welches ausgewählt wurde mit dem klick.
            }
    }

private void pictureBox_MouseClickM(object sender, MouseEventArgs e) // Wird aktiviert beim Klick auf die Box.
    {
        if (e.Button == MouseButtons.Middle) // Vergleicht den gedrückten Button mit der mittleren Maustaste, wenn zutreffend, Ausführung ausüben.
            {
                IPPC.ShowDialog(); // Anzeigen einer WinForm
            }       
    }
S
269 Beiträge seit 2010
vor 10 Jahren

(

if (moving == true /* ursprünglich if(moving)*/) // Wenn bool moving gleich true ist  

Ich kann es mir nicht verkneifen, hier eine Anmerkung zu machen: Wieso wurde hier das, vom Kommentar ausgehend, "richtigere" if(moving) zu einem if(moving == true) entgegen jedem Sinn umgeändert? (siehe auch [Tipp] Anfängerfehler == true / == false)){gray}

                startpb.Left += e.Location.X - startLocation.X; /* Nimmt den Abstand des visuellen Komponenten zur linken und zieht  
                                                                  die Startposition von der aktuellen Position ab, das ganze in der X-Koordinate. */  
                startpb.Top += e.Location.Y - startLocation.Y; /* Nimmt den Abstand des visuellen Komponenten zur rechten und zieht  
                                                                  die Startposition von der aktuellen Position ab, das ganze in der Y-Koordinate. */  

Hier liegt der Hase im Pfeffer begraben... zumindest zum Teil: Beim Klicken speicherst du dir die startLocation, beim Ziehen ziehst du von aktueller Location die Startlocation ab... bewegst du die Maus nur um einen einzigen Pixel (in X und Y Richtung), und führst diese Berechnung im Kopf durch, kommst du auf eine neue Location von ... ??? (und setzt dahin dann auch noch die linke obere Ecke des Controls selbst, anstatt von da aus wieder die Differenz zur startLocation umzurechnen) ... hier spielen mehrere logische Fehler zusammen...

so far
Karill Endusa

F
falsecode Themenstarter:in
55 Beiträge seit 2013
vor 10 Jahren

Das mit dem Kommentar war mein Fehler, hatte es nur aus Testzwecken geändert. Hab mir das nur geschrieben damit ich nicht vergesse es wieder zu ändern, hat woll nicht geklappt 🙂

Und nun zum eigentlichen Thema, mein Quellcode funktioniert, da sind keine Logikfehler drin. Ich kann ohne weiteres meine Objekte in alle Richtungen bewegen.
Das Problem das ich, sie nicht mehr bewegen kann tritt erst auf wenn ich versuche sie in das Panel zu stecken. Sprich mein Code klappt im Panel nicht.

liebe grüße
falsecode

49.485 Beiträge seit 2005
vor 10 Jahren

Hallo falsecode,

Koordinaten in Controls beziehen sich immer auf dessen linke obere Ecke. Je nachdem, wo das Panel im Form positioniert ist, unterscheiden sich die Koordinaten im Form und im Panel bezogen auf Bildschirmkoordinaten um diese Differenz.

herbivore

F
falsecode Themenstarter:in
55 Beiträge seit 2013
vor 10 Jahren

Gut ich weiss das meine Form 1280; 1024 groß ist und das Panel 956; 684,
doch welchen unterschied muss ich mir errechnen damit es wieder passt?

Und vorallem wie/wo soll ich den denn Unterschied eindrehen?
Stehe ein wenig auf dem Schlauch, seid so gut und helft mir nochmal weiter.

grüße
falsecode

F
falsecode Themenstarter:in
55 Beiträge seit 2013
vor 10 Jahren

Hab es jetzt nochmal 2 Tage versucht. Habe aber keine Idee wie Ihr das ganze realisieren würdet. Also ich kenn die Werte:
Größe Form 1280; 1024 Location Form 0; 0
Größe Panel 956; 684 Location Panel 5; 28
Größe Differenz 324; 340 Location Diffrenz 5; 28

771 Beiträge seit 2009
vor 10 Jahren

Hast du denn schon mal ge'debugged', ob überhaupt die Eventhandler angesprungen werden?

F
falsecode Themenstarter:in
55 Beiträge seit 2013
vor 10 Jahren

Wird alles angesprochen wie es sein sollte.

Hinweis von herbivore vor 10 Jahren

Wir drehen uns im Kreis. Bitte nur noch wesentliche und neue Aspekte posten.