Doublebuffered Panels -> Exception ab gewisser Größe
-
(Winforms)
Hallo zusammen.
Folgendes UserControl:
Ein gedocktes (DockingStyle=Fill) Panel mit AutoScroll=true.
Darin ein weiteres Panel eingebettet, dessen Größe vom User verändert werden kann (z.B. über eine Trackbar).Wozu das ganze: Über Abfrage der AutoScrollposition weiß ich jederzeit welcher Ausschnitt zu sehen ist. Genau in diesen Ausschnitt wird dann ein Teil eines großes Bildes gerendert. Das heißt damit hat man Scroll- und Zoomfunktionen und es geht alles sehr fix für Winforms-Verhältnisse.
Nun habe ich bemerkt, dass es irgendwann, ab einer gewissen hohen Zoomstufe (und entsprechend einem sehr großen inneren Panel) eine Exception gibt: System.ComponentModel.Win32Exception ("Für diesen Befehl ist nicht genügend Speicher verfügbar").
In einer kleinen Testanwendung konnte ich das Problem aufs verrecken nicht reproduzieren. Nach Stunden dann endlich die Lösung: In wahrheit habe ich keine normalen Panels verwendet sondern eine von Panel abgeleitete Klasse mit "this.DoubleBuffered = true;".
Und genau das ist das Problem. Einfacher Test:
Panel auf Form, Doublebuffering einschalten, über ein Button die Panelgröße schrittweise vergrößern. Irgendwo bei 20000 Pixeln Kantenlänge tritt die Exception auf.
Ohne Doublebuffering kann das Panel ohne Probleme bis 65535 Pixel vergrößert werden. Dann ist Schluß (per Design).Gleichen Problem bei einer Doublebuffered Picturebox. Ohne DB flackert meine Zoom- und Scrollbox ohne Ende.
Hat jemand eine Idee was ich nun tun könnte um das Control noch zu retten?
(Es hat auch Zeichenfunktionalitäten und ich habe wirklich keine Lust eine Scrollfunktion von Hand nachzuprogrammieren :()P.S.: Ich schätze mal das dürfte der Grund sein, warum die doublebuffered Properties bei so vielen Controls nicht public sind.
-
Interessanterweise bin ich ebend gerade auf ein ähnliches Problem gestoßen. Ich verwende AutoSize = true um mein Double Buffered Panel systematisch zu vergrößern wenn die Innenliegenden Controls vergrößert werden. Hatte nun auch genau die von dir beschriebene Exception bekommen wenn ich controls adde (warscheinlich weil beim AutoSize ja systematisch vergrößert wird). Wenn ich aber vorher SuspentLayout und hinterher ResumeLayout verwende, klappt alles wunderbar. Kannst ja mal versuchen, ggf klappt vor dem vergrößern zu suspenden und dann zu resumen.
-
Lustiger Zufall.
Funktionier aber leider nicht in meinem Fall.
-
Falls es jemanden interessiert:
1. Für das DoubleBuffering-Problem scheint es keine Lösung zu geben. Ab einer gewissen Größe tritt eine Exception mit Ursprung in unverwaltetem Code auf.
2. Die Scroll- und Zoombox konnte ich durch ein drittes, inneres Panel retten. Das äußerste Panel ist für die Scrollbalken und doublebuffered. Das mittlere Panel ist ohne doublebuffering und wird nur in der Größe geändert für die Scrollbalken. Das innerste Panel hat wieder doublebuffering und wird immer mit dem sichtbaren Ausschnitt des Bildes verschoben. Darauf wird also nun gezeichnet und es ist also stets relativ klein womit es keine Exception verursacht