Fragensteller
Paint Ereigniss einer PictureBox

Frage
-
Hallo.
Ich habe so meine Probleme mit Zeichnen zur Laufzeit. Das "soll" man ja im Paint-Ereigniss machen. Ich frage mich nur wie das gehen soll wenn man zur Laufzeit Dinge ändert. Es wird doch immer das selbe Paint-Ereigniss aufgerufen. Obwohl zur Laufzeit immer weite Dinge geszeichnet werden sollen. Dann muss man doch das ganze Paint-Ereigniss mit Abfrage voll machen.
Wenn ich z.B. am Anfang des Programms einen Kreis und einen Strich zeichnen möchte kann ich das ja in das Paint-Ereigniss schreiben. Wenn später dann noch ein Rechteck dazu kommen soll muss das doch von Anfang an in dem Ereigniss sein und zum Programmstart durch Abfragen vom Zeichnen "ausgeschlossen" werden. Sehe ich das richtig?
Meine zweite Frage ist, wie kann man das Bild einer PicturePox, dass zur Laufzeit gezeichnet wurde, copieren? Ich möchte praktisch das Bild copieren, etwas neues ausgeben und dann das alte wieder herstellen.
Danke
Jan
Alle Antworten
-
Hallo Jan,
wenn die zu zeichnenden Elemente zur Laufzeit wechseln, so kannst Du sie in einer Auflistung verwalten.
Die dafür benötigten Einzel-Elemente kann von einer gemeinsamen Basisklasse ableiten
oder ihnen eine Schnittstelle verpassen, über die sie gezeichnet werden.Zur zweiten Frage: Du kannst die Bitmap dir eine Kopie über die Bitmap.Clone-Methode erzeugen.
Um das ursprüngliche Bild wiederherzustellen sichere den Verweis Image-Eigenschaft in einer Variable.Gruß Elmar
-
Hallo :)
Ich habe das ganze jetzt mit der Image-Eigenschaft und einer Bitmap hinbekommen. Aber wie darf mich keiner fragen denn ich verstehe das ganze nun nicht mehr ganz. Hierzu ein kleines Beispiel:
Public Class Form1 Dim z As Graphics = CreateGraphics() Dim Puffer As New Bitmap(500, 500) Dim PufferGraphics As Graphics = Graphics.FromImage(Puffer) Dim stift As New Pen(Color.Red, 2) Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click PufferGraphics.DrawLine(stift, 0, 0, 100, 100) PictureBox1.Image = Puffer End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click PictureBox1.CreateGraphics.DrawLine(stift, 50, 0, 100, 100) End Sub End Class
Was ich nun nicht verstehe ist, dass der Strich von Button1 den ich über den Puffer in die PictureBox male nicht verschwindet wenn ich das Fenster des Programmes z.B. verkleiner oder aus dem Bild ziehe. Der von Button2 ist dann weg und so "soll es ja auch sein" weswegen man ja das Paint-Ereigniss der PictureBox nutzen sollte um in ihr zu zeichnen.Aber warum verschwindet der erste Strich nicht? Ich copiere ihn doch nur ein mal in die PictureBox und nicht immer wieder?!?
Gruß
Jan -
Hallo Jan,
Du malst nicht wirklich in der PictureBox, sondern in der Grafik (Puffer), die Du der PictureBox zugewiesen hast.
Und solange Du immer die gleiche Bitmap verwendest und nichts löscht, bleiben alle Malereien erhalten.Eine Möglichkeit ist es, die Bitmap jeweils zu löschen, was u. a. über Graphics.Clear geht.
Eine andere die Bitmap wegzuwerfen und von vorne anzufangen - eher für solche Fälle
wo man schon eine Vorlage hat - z. B. ein Bild aus einer Datei lädt.Gruß Elmar
-
Hallo Elmar,
ich denke, dass da was falsch rübergekommen ist. Ich finde es positiv, dass das Bild so erhalten bleibt und frage mich warum man dann überhaupt noch das Paint-Ereigniss nutzen soll. So ist es, zumindest in meinem Fall, viel einfacher...
Trotzdem danke für die Anregungen
Jan
-
Hallo,
auf eine Bitmap malen ist was für "Dummies" - da relativ ineffizient.
Denn zuerst malt man ein, zwei Striche und Kreise. um danach die gesamte Bitmap
via DrawImage auf den Bildschirm zu kopieren (mehr tut eine PictureBox nicht).Bei heutige Grafikkarten und kleinen Bitmaps mag das egal sein.
Werden die Zeichnungen (hier Bitmaps) größer oder wechseln sie häufig den Inhalt,
sieht das schon anders aus.Richtige Grafik-Programme (ala AutoCad, Maya Blender etc.) verwenden
auch heute viel Zeit auf eine Optimierung der Zeichenroutinen.
Wobei ein Großteil in der Grafikkarte (GPU) steckt,
nur damit sind heutige Spiele überhupt möglich - siehe z. B. ShaderNur GDI+ nutzt davon gar nix - da gilt noch Handarbeit, siehe Verwalteter Code in GDI+
Gruß Elmar -
Hallo,
auf eine Bitmap malen ist was für "Dummies" - da relativ ineffizient.
Denn zuerst malt man ein, zwei Striche und Kreise. um danach die gesamte Bitmap
via DrawImage auf den Bildschirm zu kopieren (mehr tut eine PictureBox nicht).Bei heutige Grafikkarten und kleinen Bitmaps mag das egal sein.
Werden die Zeichnungen (hier Bitmaps) größer oder wechseln sie häufig den Inhalt,
sieht das schon anders aus.Richtige Grafik-Programme (ala AutoCad, Maya Blender etc.) verwenden
auch heute viel Zeit auf eine Optimierung der Zeichenroutinen.
Wobei ein Großteil in der Grafikkarte (GPU) steckt,
nur damit sind heutige Spiele überhupt möglich - siehe z. B. ShaderNur GDI+ nutzt davon gar nix - da gilt noch Handarbeit, siehe Verwalteter Code in GDI+
Gruß ElmarUnd das ganze soll mir jetzt bitte was sagen und wie helfen? Du hast es erkannt, ich bin ein Dummie und möchte in Visual Basic sicher kein richtiges Grafik-Programm (ala AutoCad etc) programmieren. Es geht mir im Moment einfach nur darum zur Laufzeit Grafiken zu verändern, hinzu zu fügen und wieder zu löschen. Und das ganze am einfachsten so, dass die ganze Grafik auch da bleibt nachdem eine MessageBox über ihr eingeblendet wurde. Soweit ich das mit meinem jetzigen Know-how in VB erkannt habe geht das über das Zeichnen im Puffer für mich z.Z. am einfachsten und vor allem am verständlichsten. Denn das Paint-Event habe ich zwar realisiert aber noch nicht ganz verstanden. Ich weiß z.B. noch nicht wie ich da so nach und nach Elemente der Grafik hinzufüge oder wieder lösche. Denn ich feuere ja immer das selbe Event. Und um im Laufe des Programmes verschieden Dinge zu zeichnen kann ich diesen Event z.Z. nicht zur Laufzeit ändern. Aber um im Laufe des Programmes verschiedene Dinge zu zeichnen müßte aus meiner jetzigen Dummiesicht ja verschiedener Code in dem Event stehen. Zum Start z.B. "zeichne A und B", später dann "zeichne A und B und C" und noch später z.B. "lass A weg und zeichne B und C". Du siehst, ich bin ein Dummie und wüßte im Moment absolut nicht wie ich das mit nur einem Event realisieren kann. Sicher kann ich dort div. Abfragen einbauen aber ich weiß jetzt selber noch nicht was ich später so alles zeichnen werde...
Sei nicht böse über diese Raktion von mir aber ich weiß echt nicht was Du mir gerade sagen wolltest. Ausser, dass ich ein Dummie bin... Und das ist a) völlig richtig, b) doch nichts schlimmes und c) ein Status in dem fast alle hier angefangen haben, oder? Denn schließlich bin ich ja auch deswegen hier um Hilfe von Leuten wie Dir zu bekommen ;-)
Gruß
Jan -
Eine einfache Lösung ist, im Paint Ereignis die Oberfläche zu löschen und dann jedes Element zu “malen”. Dafür wird eine Liste angelegt (ich bezeichne sie mal als DisplayList), deren Elemente “gemalt” werden. Durch Löschen und Hinzufügen einzelner Objekte kann die Sichtbarkeit beeinflusst werden.--
Viele Gruesse
Peter -
Hallo Jan,
"Dummy" sein ist nichts Anstößiges, da gibt es ganze Buchserien.
Aber solche Antworten provoziert man mitfrage mich warum man dann überhaupt noch das Paint-Ereigniss nutzen soll.
Wenn Dir Thorsten (der nebenbei viel in dem Bereich macht) in
per Mausklick in eine PictureBox zeichnen
zeigt wie man es machen könnte, so solltest Du das wenigsten versuchen.
Nicht verstehen wäre in Ordnung, nur dort kam nicht mal eine Reaktion.
Nichts anderes habe ich und Peter vorgeschlagen.
Und ja, in der Realität wird es umfangreicher. Window macht es sich da einfach:
Zeichne mich, das wie ist dem Entwickler überlassen - When to Draw in a WindowGruß Elmar