Entwickler-Ecke

C# - Die Sprache - Multithreading+Steuerelemente bewegen


MysteryEskimo - Fr 15.06.07 20:00
Titel: Multithreading+Steuerelemente bewegen
Ich wollte ein Game machen in dem ich ein weißes kästchen (PictureBox) über das Fenster sausen lasse und man muss draufklicken. Aber da hab ich ein Proble: während das Fenster in der Methode pbBewegen() übers Fenster saust, ist das Fenster noch gar nicht da! Ich ruf die Methode pbBewegen() übrigens im Konstruktor auf.
Wenn ich es mit Multithreading probiere, kann jedoch ich auf das Steuerelement PictureBox1 nicht zugreifen!
Langsam gehen mir die Ideen aus... :(

Hier der Quelltext:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
private void pbBewegen(PictureBox pb)
        {
            InitializeComponent();
            Random r = new Random();
           int hoehe = r.Next(1240);
           for (int i = 5; i < 245; i++)
           { pb.Location = new Point(i, hoehe);
           Thread.Sleep(100);
       }
        }

//Konstouktor:
public Form1()
        {
            InitializeComponent();
            pbBewegen(pictureBox1);
        }


Moderiert von user profile iconChristian S.: C#-Tag repariert


Christian S. - Fr 15.06.07 20:08

Hallo!

Erst einmal rufst Du InitializeComponent in Deiner eigenen Methode nochmal auf, das gehört da nicht hin ;)

Wenn Du aus einem anderen Thread auf die GUI zugreifen willst, dann schau Dir mal in der Hilfe etwas zu Invoke an (weiß nicht, in welcher Klasse das eingeführt wird, aber Form hat's ganz sicher). Da gibt es auch einige Code-Beispiele in der Hilfe.

Im Konstruktor, wo Du Deine Methode aufrufst, ist die Form natürlich noch nicht sichtbar. Ruf die Methode in einem geeigneten Ereignis auf. Ich glaube, Validated dürfte passen. Du musst nur schauen, dass Du die Methode nur beim ersten Mal aufrufst, wenn das Ereignis ausgelöst wirst. Am Besten über eine bool-Variable, die beim ersten Mal gesetzt wird.

Grüße
Christian


MysteryEskimo - Fr 15.06.07 20:45
Titel: Re
Ja, ich weiß jetzt wie ich es machen könnte aber ein Problem gibt es noch:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
public Form1()
        {
            InitializeComponent();
            ;
            this.Invalidated += new InvalidateEventHandler(Form1_Invalidated);
        }

        void Form1_Invalidated(object sender, InvalidateEventArgs e)
        {
            Thread t = new Thread(new ThreadStart(pbBewegen));
            t.Start();
        }

        private void pbBewegen()
        {
            
            Random r = new Random();
           int hoehe = r.Next(1240);
           for (int i = 5; i < 245; i++)
           { pictureBox1.Location = new Point(i, hoehe);
           Thread.Sleep(100);
       }
        }


Aber mit dem zweiten Thread kann ich nicht auf den ersten zugreifen- dann gibt es einen Ausnahmefehler!

Moderiert von user profile iconChristian S.: C#-Tag repariert


Christian S. - Fr 15.06.07 21:09

Wie ich sagte: Invoke in der Hilfe nachschlagen


Kha - Sa 16.06.07 11:08

Ein Timer wäre die einfachste Lösung, Game-Loops werden nur für aufwendigere Spiele ebnötigt - und multithreaded erst recht nicht ;) .


John Sanson - So 17.06.07 21:31

Bei deinem Thread Problem sollte

C#-Quelltext
1:
CheckForIllegalCrossThreadCalls = false;                    

helfen


Kha - Mo 18.06.07 13:55

Das ist nicht dein Ernst, oder? Hast du überhaupt eine Ahnung, was diese Zeile bedeutet?


MysteryEskimo - Mi 20.06.07 12:34
Titel: re:<...>solltehelfen
zu welchem Objekt gehört diese Eigenschaft?


Kha - Mi 20.06.07 17:37

Falls du das nicht selbst herausfinden kannst, werden dir auch auf keinen Fall die erheblichen Konsequenzen dieser Eigenschaft bewusst sein.
Ich sage es noch einmal: Es gibt keinen Grund, bei diesem Problem Multithreading einzusetzen und du wirst erst recht wohl nie auf irgendein Problem stoßen, bei dem du den Cross-Thread-Check deaktivieren musst. Benutze einen Timer und erfreue dich an seiner Einfachheit.

PS: Schon meine zwei Fragen am Montag sollte eine Warnung für dich gewesen sein, dass diese Eigenschaft allein auf einen Holzweg führen kann.