Laden...

Raster in Onpaint zeichnen

Erstellt von inek vor 14 Jahren Letzter Beitrag vor 12 Jahren 5.817 Views
inek Themenstarter:in
182 Beiträge seit 2007
vor 14 Jahren
Raster in Onpaint zeichnen

Hallo zusammen,
ich hatte vor in der OnPaint Methode ein raster auf meine form zu zeichnen um verschiebbare element besser anordnen zu können.

Da bei einer leeren Form ein Raster super fies anzusehen ist, habe ich mich für kleine punkte entschieden und führe im OnPaint folgenden Code aus:


protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            this.graphics = e.Graphics;

            //draw Grid
            if (this.showGrid)
            {
                //calculate ViewArea
                this.viewArea = new Rectangle(new Point(0, this.menueStrip.Height), new Size(this.Width, this.Height - this.menueStrip.Height - this.statusStrip.Height));
                Rectangle point = new Rectangle(viewArea.Location, new Size(1, 1));

                //draw points
                int tmpWidth = 0;
                while (tmpWidth <= viewArea.Right)
                {
                    int tmpHeight = viewArea.Top;
                    while (tmpHeight <= viewArea.Bottom)
                    {
                        point.Location = new Point(tmpWidth, tmpHeight);
                        g.DrawEllipse(Pens.DarkBlue, point);
                        tmpHeight += this.gridSquare.Height;
                    }
                    tmpWidth += this.gridSquare.Width;
                }
            }
        }

funktioniert auch ... solange ich drüberliegende elemente nicht verschiebe..
dann flackerts ohne ende..

ich denke mal das das flackern daher kommt, das in jedem paint-vorgang ALLE punkte neu gezeichnet werden oder ?

hat jemand evtl. nen tipp wie ich es besser machen kann ?

3.511 Beiträge seit 2005
vor 14 Jahren

Hallo,

um Raster zu zeichnen biete die Klasse ControlPaint die Methode DrawGrid an.

Kannst du ja mal einbauen und schauen, ob es von der Performance her besser ist. Desweiteren kannst du auch mal [Artikel] Flackernde Controls und flackerndes Zeichnen vermeiden durchlesen.

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

E
2 Beiträge seit 2009
vor 14 Jahren

Hallo inek,

Versuch doch mal deiner Form ein Hintergrundbild zuzuordnen, welches dein Raster darstellt.

inek Themenstarter:in
182 Beiträge seit 2007
vor 14 Jahren

Hi, danke für dei schnellen Antworten.
Das mit dem Hintergrundbild hab ich schon versucht.. wird nur noch schlimmer 😃
DrawGrid werde ich mir jetzt mal anschaun.

inek Themenstarter:in
182 Beiträge seit 2007
vor 14 Jahren

Das mit dem DrawGrid ist perfekt.. vielen dank..
weisst du noch wie ich die Farbe des Rasters dann genau festlegen kann ?
in der DrawGridmethode kann nur die Farbe hinter dem raster angegeben werden und die Rasterfarbe wird anhand dieser berechnet.

3.511 Beiträge seit 2005
vor 14 Jahren

Hi,

das funktioniert mit der Methode nicht. Du kannst dir aber im Reflector den Code der Methode anschauen und diesen Code bei dir verwenden mit der Änderung, das man die Rasterfarbe angeben kann.

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

Gelöschter Account
vor 14 Jahren

bei deinem ersten post zeichnest du ja jedemenge rechtecke. das ist von der ersten überlegung zwar korrekt, da man ja rechtecke braucht. im 2. schritt jedoch sollte man überlegen, welche seiten eines rechteckes nciht gezeichnet werden müssen, weil ja alle rechtecke nebeneinander liegen.

gerade dieser gedanke "was muss nciht gezeichnet werden" ist etwas fundamentales in der gdi+ programmierung.

wenn du einfach nur ein grid zeichnen willst, dann wäre doch auch eine ansammlung von horizontalen und vertikalen linien mit bestimmten abständen ausreichend. für das menschliche auge ergibt es dann ein grid 😉

das ist bedeutsam perfomanter da sich die doppelt gezeichneten bereiche nur auf die schnittpunke der linien beschränken und nicht auf alle außenkanten der suggerierten rechtecke.

inek Themenstarter:in
182 Beiträge seit 2007
vor 14 Jahren

so.. Danke nochmal für eure Hilfestellung..
habs jetzt so gelöst:


public static void DrawGrid(Graphics graphics, Rectangle area, Size pixelsBetweenDots, Color color)
        {
            // Check parameters
            if (null == graphics)
                return;

            int num2 = 0x10;
            int width = ((num2 / pixelsBetweenDots.Width) + 1) * pixelsBetweenDots.Width;
            int height = ((num2 / pixelsBetweenDots.Height) + 1) * pixelsBetweenDots.Height;
            Bitmap bitmap = new Bitmap(width, height);
            for (int i = 0; i < width; i += pixelsBetweenDots.Width)
            {
                for (int j = 0; j < height; j += pixelsBetweenDots.Height)
                {
                    bitmap.SetPixel(i, j, color);
                }
            }
            Brush gridBrush = new TextureBrush(bitmap);
            bitmap.Dispose();

            // Draw grid
            graphics.FillRectangle(gridBrush, area);
        }

Gelöschter Account
vor 14 Jahren

sry wenn ich das sage aber das ist keine gute lösung.

bevor ich aber anfange zu meckern, würde ich gerne wissen, von wo genau diese methode wie oft aufgerufen wird.

inek Themenstarter:in
182 Beiträge seit 2007
vor 14 Jahren

wieso keine gute lösung ?

wir nur in OnPaint verwendet.. performance ist perfekt

6.911 Beiträge seit 2009
vor 14 Jahren

Hallo inek,

ein Hinweis zur Bitmap-Variante:
Auf den TextureBrush kannst du verzichten denn mit graphics.DrawImage(bitmap, 0, 0) kannst du die Bmp direkt auf die Zeichenfläche malen.

Auch auf die Bitmap kannst du verzichten (wie JAck30lena oben auch erwähnt hat). Mit horizontalen und vertikalen Linien erreichst du dasselbe und das ist im Sinne von GDI+ korrekter.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

inek Themenstarter:in
182 Beiträge seit 2007
vor 14 Jahren

Ja habe ich beides versucht und bekomme es dadurch nicht wirklich performant hin... einzige lösung die am wenigsten ziet kostet ist die die ich gepostet habe..

Anscheinend ist die drawimage methode wesendlich langsamer

Gelöschter Account
vor 14 Jahren

Anscheinend ist die drawimage methode wesendlich langsamer

sry, aber dann hast du etwas wesentliches falsch gemacht.

selbst 1000 horizontale und vertikale linien mit drawing malen ist schneller, als jedesmal ein bitmap zu erstellen und mit setpixel linien zu zeichnen....

2.760 Beiträge seit 2006
vor 14 Jahren

Nun er möchte ja auch kein Gitter sondern ein gepunktetes Raster.

Gelöschter Account
vor 14 Jahren

ok. aber es muss immer schneller gehen als immer ein neues bitmap zu erzeugen und dann zeichnen zu lassen.

2.760 Beiträge seit 2006
vor 14 Jahren

Klar, eins würde reichen. Das müsste dann gecached werden und nur wenn sich das Gitter ändert neu erzeugt werden.
Wahrscheinlich ist es allerdings ganz ohne das Bitmap (zumindest bei einem großen Raster) doch noch ein ganzes Stück schneller bzw. speichersparender.

Gelöschter Account
vor 14 Jahren

als hint: nimm einen eigens definierten Pen mit Dashstyle.Dot und dem gefordertem DashOffset. das müsste so funktionieren. dann kannst du die bitmapsache weglassen.

2.760 Beiträge seit 2006
vor 14 Jahren

Dann reicht es auch dicke nur die Vertikalen oder Horizontalen "Linien" zu zeichnen wenn es alles gleichmäßige Abstände hat. Das sollte der schnellste Weg sein.

Gelöschter Account
vor 14 Jahren

sry, nciht DashOffset sondern DashPattern musst du festlegen.

z.b. myPen.DashPattern = new float[]{1,10}; bedeutet das die dots 1 pixel groß sind und zwischen den dots 10 pixel abstand sind.

inek Themenstarter:in
182 Beiträge seit 2007
vor 12 Jahren

Sry.. hatte eure Anmerkungen so umgesetzt.. aber leider verpeilt nochmal zu posten.. Danke nochmal an alle.. 😃