Fenster-/Picturebox Inhalt erhalten. ("AutoRedraw")!?
-
Hallo!
Ich habe schon überall im Internet gesucht, aber leider noch nichts gefunden...
Ich habe eine Form/ oder auch eine Picture Box in die per Graphics gezeichnet wird.
Wenn man jedoch ein anderes Fenster drüberzieht, und dann wieder wegschiebt ist der Inhalt wieder weg, soweit klar. Ich habe das ganze Zeichnen in eine Funktion ausgelagert, die ich einfach in den Ereignissen aufrufen kann.Das mache ich mittlerweile in fast allen, der Inhalt wird auch meistens gezeichnet. Wenn ich jedoch z.B. das Fenster minimiere und dann wieder maximiere ist der Inhalt weg. Er *erscheint für einen kurzen Moment*, dann ist er wieder weg. Gleiches gilt auch wenn ich ein anderes Fenster über mein Programm lege und dann wieder wegziehe (s.o.)
Wieso wird der Inhalt wieder gelöscht?
Danke!
stefffi
-
stefffi schrieb:
Ich habe das ganze Zeichnen in eine Funktion ausgelagert, die ich einfach in den Ereignissen aufrufen kann.
Rufst du die Funktion auch aus dem "Paint" Event auf?
-
Ja
-
Du solltest deinen Zeichencode nur im Paint Event haben, und nirgends anders.
Auch solltest du nur mit dem Graphicsobjekt vom Paint Event arbeiten und dir keins selber erstellen, damit gibts nur Schwierigkeiten.Und dann kann schon eigentlich fast gar nichts mehr schiefgehen, weil dein Paint Event immer dann aufgerufen wird, wenn was neugezeichnet werden muss, um nen neuzeichnen brauchst du dich eiegntlich gar net kümmern.
-
Problem:
Der Fensterinhalt muss jedesmal vollständig neu gezeichnet werden, da er zB beim Resize skaliert werden muss.
Wenn ich das Fenster verkleinere wird gar kein Paint ausgelöst.
Wenn ich das Fenster vergrößere Zeichnet er nur den kleinen Bereich der neu dazu gekommen ist neu, der rest bleibt unskaliert.stefffi
-
Du kannst mit Invalidate nen neuzeichnen erzwingen.
-
Hallo Zusammen,
bin auf der Suche nach einer Lösung für mein Problem auf diesen Thread gestoßen! Das ist genau der Problemfall, denn ich im Moment auch habe. Immer wenn ich mein Fenster minimiere und wieder öffne, dann sind die Graphen in meinen beiden PictureBox'en weg. Die Kurven werden per Dropdown-Menu- und Button Click-Events in die PictureBox'en gezeichnet. Wie bringe ich denn da jetzt das oben genannte Paint-Event rein ????????
Muss ich jetzt im Button_Click Event das Paint_Event aufrufen, und dann sämtliche Aufrufe meiner Klasse, die für das Zeichnen zuständig ist, in das Paint_Event schreiben ???
Hätte jemand vieleicht ein kleines Beispiel????
Schon mal VIELEN DANK !!!
-
Also hab das ganze Zeichnen nun kapiert! Eine Frage hab ich aber noch: Und zwar zeichne ich nun in ein Panel über das Paint-Event, nur wird das natürlich auch schon aufgerufen, beim öffnen der Applikation. Wie kann ich im Paint-Event bestimmen, dass es nur bei den jeweilegen Buttons ausgeführt wird?
Habs schon mit if(Button->Click) versucht, aber da bringt er mir den Fehler:
Für die Syntax muss "System::Windows::Forms::ToolStripItem::Click" ein Datenmember sein.Wie gehts???
-
Du könntest mit Flags arbeiten die gesetzt werden, wenn die Buttons gedrückt sind. Eleganter fände ich aber folgendes:
Leg eine Klasse (bzw. Interface) an, die eine Schnitstelle für das Zeichnen der Elemente bereit stellt. Danach kannst Du eine Liste o.Ä. mit diesen Objekten führen.
Implementiere dann für die einzelnen Buttons die Zeichenoperationen. Wenn diese gezeichnet werden sollen, hängst Du das Objekt einfach ein.
(Achtung: Pseudocode mit C# vermischt)
public interface ICustomDraw { void Draw(<Das Grafikobjekt oder auf was halt gezeichnet werden soll>); } public class Button1Drawer : ICustomDraw { void Draw(<Das Grafikobjekt oder auf was halt gezeichnet werden soll>) { // Für Button1 spezifische Zeichnungen vornehmen } } public class Button2Drawer : ICustomDraw { void Draw(<Das Grafikobjekt oder auf was halt gezeichnet werden soll>) { // Für Button1 spezifische Zeichnungen vornehmen } } public class Button3Drawer : ICustomDraw { void Draw(<Das Grafikobjekt oder auf was halt gezeichnet werden soll>) { // Für Button3 spezifische Zeichnungen vornehmen } }
List<ICustomDraw> customDrawList; void Button1_Click(...) { // Code einfügen, der entsprechend nur 1 Drawer in die Liste einführt oder // fals gewünscht bei jedem Klick einen addiert Button1Drawer drw = new Button1Drawer (); customDrawList.Add(drw); } void Panel_OnPaint(...) { // Basiszeichnung ausführen // nun die Customdraws foreach(ICustomDraw drw in customDrawList) drw->Draw(<Grafikobjektübergeben>); }
Das ganze schicke ich mal als grobes Konzept. Ob sich der Overhead lohnt hängt von den Zeichenoperationen ab.
Das schöne daran wäre aber, das es frei von Erweiterungen ist. Du kannst einfach weitere Objekte in diese Liste einarbeiten. Du könntest sogar Objekte definieren, die nur einmal zeichnen und sich selbst aus der Liste austragen.
-
Hallo,
schon mal mortz dank für die Infos! Ich denke aber, das mit der List ist bei mir nicht zwingend erforderlich, denn im Grunde zeichne ich immer das selbe nur mit anderen Werten. Leider hab ich immer noch in meinem Fall Probleme mit der Darsetllung! Und zwar hab ich 2 Panels nebeneinander, darüber befinden sich verschiedene Auswahlmöglichkeiten für die einzelnen Panels. Die Panels sollen voneinander getrennt bezeichnet werden.Ich versuchs mal mit einem Bsp.: Im ersten Panel wir der Graph A zu B ausgewählt ... geht! Danach wird für den 2 Panel Graph B zu D ausgewählt, es soll aber Panel 1 unverändert bleiben! usw ...
Ich habs bisher mit zwei bool`schen Variablen und einem if fall in jedem Paint_Ereignis, dürfte dass gleiche wie die Flags bewirken, oder ?. Setzte also in den Click_events die Variablen auf true oder false, dass geht aber irgendwie nicht ? Es wird trotzdem in das andere Panel gezeichnet, oder beim maximieren des Fensters gibts Probleme ???
private: System::Void panelGraphL_Paint(System::Object^ sender, System::Windows::Forms::PaintEventArgs^ e) { if(panel1erlaubt) { System::Drawing::Graphics^ grfx = e->Graphics; graph.zeichneKurve(grfx); } } private: System::Void panelGraphR_Paint(System::Object^ sender, System::Windows::Forms::PaintEventArgs^ e) { if(panel2erlaubt) { System::Drawing::Graphics^ grfx = e->Graphics; graph.zeichneKurve(grfx); } }
im Clickevent steht dann:
panel1erlaubt = true; panel1->Invalidate()
-
Kann mir denn niemand einen Tip geben ????
Ich habs jetzt auch schon mit einer List versucht, wie im Tutorial beschrieben. Aber das funzt insofern nicht, da ich ja mit "for each" für jedes Element angebe, zeichnet es bei z.B 4 ELementen also 4mal Add(...) 4 mal die gleiche Graphik übereinander... (is irgendwo klar)
An welcher Stelle müsste ich die Liste leeren ???
VIELEN DANK
-
Die liste leert man an der Stelle, an der man sie leeren will. Es weiß ja keiner was Du im Detail machst, also kann Dir keiner sagen wann Du die Operation nicht mehr zeichnen wilsst.
Aus der Liste löscht man die Operation wenn man sie halt nicht zeichnen will. Wie das passiert ist wieder offen und kann auf verschiedenste Wege erledigt werden.