Form1_Paint wird öfters als 1x aufgerufen

Xo-mate

Erfahrenes Mitglied
Hi.
Also ich hab ne Form1_Paint Methode und diese wird nicht (wie ich es erwarten würde) ein mal aufgerufen, sondern jedes mal nachdem sich ein Button aufgebaut hat.
Das ist ziemlich nervig und auch nicht schön für die Performance.

Wie mach ich das weg bzw. halt so, dass es nur einmal aufgerufen wird?
 
Hi Xo-mate,

wenn du deine Methode zum Zeichnen nur einmal aufrufst, dann siehst du sobald sich die Form neuzeichnet deine Grafik nicht mehr, weil diese nicht mehr mit gezeichnet wird...

Um deine Performance zu verbessern, wäre ein bisschen Code nicht schlecht.
Bzw. Was willst du denn konkret machen?

mfg,
chrstn
 
Also das ganze ist so, dass ich in Form1_Paint mit GDI+ einiges zeichne (ca. 100 Bilder).
Wenn ich das Programm starte (und auch nur dann) wird die Paint-Methode halt öfters aufgerufen und zwar nachdem jeder Button angezeigt wird einmal (die Buttons bauen sich ja auch nicht gleichzeitig, sondern nach und nach auf).

Der Code ist einfach nur ein GraphicObject in das die Grafiken gezeichnet werden und dann angezeigt werden.
 
hmm... nö
der zeigt das dann alles gar nicht erst an.
Ich hab dafür aus
gO = this.CreateGraphics();
das gemacht:
gO = PictureBox1.CreateGraphics();

gO ist ein global definiertes GraphicObject.
gesetzt wird es in der ersten Zeile von Form1_Paint.
Es sollte jetzt ja das gleiche rauskommen - es kommt aber nichts.
 
Uhh.... nimm kein globales Graphics-Objekt. Wozu brauchst das denn? Bekommst im Paint-Event doch immer ein frisches!

Wenn du versuchen möchtest, in der PictureBox das ganze zu zeichnen, abonniere das Paint-Event der PictureBox!

die Buttons bauen sich ja auch nicht gleichzeitig, sondern nach und nach auf).

Wie/Wo/Wann erzeugst du diese Buttons? Einmalig beim Starten beziehungsweise einmalig aufgrund eines bestimmten Ereignisses neu?

Könntest vor dem Erstellen/Hinzufügen des ersten Buttons SuspendLayout und nach dem Letzten ResumeLayout aufrufen.

Ansonsten würde ein Überblick auf deinen Code uns auch ein wenig helfen.

Lg, Alex
 
Das solltest du 1. in die Sub Picturebox1_Paint setzen und 2. kannst du auch direkt e.Graphics verwenden...


Edit: Da war wohl jemand schneller als ich :)
 
Zuletzt bearbeitet:
gO ist global, da es auch in anderen Methoden modifiziert wird.

Die Buttons werden so aufgrufen, wie VS05 es von Natur aus macht. Hab ich nichts dran geändert. Keine Ahnung wie man das überhaupt ändert.
Hab ich SuspendLayout korrekt eingesetzt?

Ich denke der Einblick hilft nicht weiter, da das alles mit Variablen übersäht ist.

Code:
                this.SuspendLayout();
                //Felder zeichen
                int scrollshiftx = scrollButtonPosX * gridboxesx;
                int scrollshifty = scrollButtonPosY * gridboxesy;
                for (int i = 0; i <= gridboxesx - 1; i++)
                    for (int j = 0; j <= gridboxesy - 1; j++)
                    {
                        if (fields[i + scrollshiftx, j + scrollshifty] == 0) gO.DrawImage(iLMap.Images[0], i * gridboxsizex + gridshiftx, j * gridboxsizey + gridshifty); //Wasser
                        else if (fields[i + scrollshiftx, j + scrollshifty] == 1) gO.DrawImage(iLMap.Images[1], i * gridboxsizex + gridshiftx, j * gridboxsizey + gridshifty); //Wüste
                        else if (fields[i + scrollshiftx, j + scrollshifty] == 2) gO.DrawImage(iLMap.Images[2], i * gridboxsizex + gridshiftx, j * gridboxsizey + gridshifty); //Wiese
                        else if (fields[i + scrollshiftx, j + scrollshifty] == 3) gO.DrawImage(iLMap.Images[3], i * gridboxsizex + gridshiftx, j * gridboxsizey + gridshifty); //Moor
                        else if (fields[i + scrollshiftx, j + scrollshifty] == 4) gO.DrawImage(iLMap.Images[4], i * gridboxsizex + gridshiftx, j * gridboxsizey + gridshifty); //Ackerland
                        else if (fields[i + scrollshiftx, j + scrollshifty] == 5) gO.DrawImage(iLMap.Images[5], i * gridboxsizex + gridshiftx, j * gridboxsizey + gridshifty); //Wald
                        else if (fields[i + scrollshiftx, j + scrollshifty] == 6) gO.DrawImage(iLMap.Images[6], i * gridboxsizex + gridshiftx, j * gridboxsizey + gridshifty); //Gebirge
                        else if (fields[i + scrollshiftx, j + scrollshifty] == 7) gO.DrawImage(iLMap.Images[7], i * gridboxsizex + gridshiftx, j * gridboxsizey + gridshifty); //Steine


                        if (fields[i + scrollshiftx, j + scrollshifty] > 1) //Wasser und Wüste nicht abfragen
                        {
                            for (int k = 0; k < building.Count; k++)
                            {
                                //Zeichnet gebäude und besitzer und w8ts
                                if (int.Parse(building[k][0]) == i + scrollshiftx && int.Parse(building[k][1]) == j + scrollshifty && int.Parse(building[k][2]) >= 0)
                                {
                                    gO.DrawImage(iLBuilding.Images[int.Parse(building[k][2])], i * gridboxsizex + gridshiftx, j * gridboxsizey + gridshifty);
                                    
                                    //Besitzeranzeige
                                    //Aktueller Spieler
                                    if (building[k][5] == currentplayer.ToString())
                                    {
                                        SolidBrush myBrush = new SolidBrush(Color.Plum);
                                        gO.FillRectangle(myBrush, int.Parse(building[k][0]) * gridboxsizex + gridshiftx + gridboxsizex - 7, int.Parse(building[k][1]) * gridboxsizey + gridshifty, 6, 6);
                                    }
                                    else //Andere Spieler
                                    {
                                        SolidBrush myBrush = new SolidBrush(Color.Red);
                                        gO.FillRectangle(myBrush, int.Parse(building[k][0]) * gridboxsizex + gridshiftx + gridboxsizex - 7, int.Parse(building[k][1]) * gridboxsizey + gridshifty, 6, 6);
                                    }

                                    //W8s makieren
                                    if (building[k][4] != "0")
                                    {
                                        Pen myPen = new Pen(Color.Gray);
                                        gO.DrawRectangle(myPen, int.Parse(building[k][0]) * gridboxsizex + gridshiftx + 4, int.Parse(building[k][1]) * gridboxsizey + gridshifty + 4, 22, 22);
                                        //gO.FillRectangle(myBrush, int.Parse(building[i][0]) * gridboxsizex + gridshiftx + gridboxsizex - 7, int.Parse(building[i][1]) * gridboxsizey + gridshifty, 6, 6);                        
                                    }
                                }
                            }
                        }                       
                    }

                generateScrolls();
                this.ResumeLayout();
 
Zuletzt bearbeitet:
Hi

Das Paint-Event wird bei jedem Neuzeichnen des Controls aufgerufen. Wenn du in dieser Methode einen Breakpoint setzt, wird jedes mal bei Wechsel zwischen VS und deiner Anwendung die Methode aufgerufen.
Du kannst das ganz einfach nachtesten:
Inkrementier in der OnPaint-Methode einen Counter und lass ihn nach Abschluss aller Vorgänge beim Laden der Form ausgeben. Normalerweise sollte der Counter dann bei 1 stehen.

Ggf solltest du auch Suspend- und ResumeLayout weglassen und dafür DoubleBuffering für die Form aktivieren
 
Form1_Paint wird 11 mal aufgrufen (ich habe 10 Controls plus die Form => sind 11).
Des Weiteren wird es jedes mal aufgerufen, wenn ich über einen Button gehe (der verändert sich dann ja). Das habe ich aber bis jetzt so gelöst, dass er das Spielfeld nur dann aufbaut, wenn sich der Mauszeiger über dem Spielfeld befindet, was natürlich nicht so toll ist, wenn man Alt-Tab o.ä. macht, da das Spielfeld dann ja auch weg ist, aber nicht neu aufgebaut wird.
DoubleBuffering ist an.
 

Neue Beiträge

Zurück