Das merkwürdige Verhalten von „LargeChange“ bei Scrollbars

Ich erlebe ja so einiges beim Programmieren, oftmals, weil ich Fehler gemacht habe, aber hin und wieder stehe ich vor einem Problem, bin mir sicher, alles richtig gemacht zu haben, und trotzdem passiert nicht das, was ich erwarte. So auch vor ein paar Tagen, als ich mich eine ganze Weile mit Bildlaufleisten (engl. Scrollbars) auseinandersetzten musste. Gezwungener Maßen „eine ganze Weile“, muss ich sagen, denn eigentlich hätte ich nach 5 Minuten fertig sein müssen.

Für ein Projekt habe ich mir eine Bildanzeige gebastelt, die – natürlich – Bilder anzeigen sollte, diese aber auch vergrößern und verkleinern sollte. Dementsprechend brauchte ich Bildlaufleisten, damit ich auch die Teile eines Bildes anzeigen kann, die außerhalb des Sichtfensters liegen. Um eine möglichst vielseitig einsetzbare Software zu haben, sollte es egal sein, wie groß das geladene Bild ist, weshalb die Bildlaufleisten dynamisch an das Bild und den gewählten Bildausschnitt angepasst werden. Zumindest war das mein Wunsch. Zusätzlich sollte auch die Größe des Programms anpassbar sein, was sich widerum auf den Bildausschnitt und die Bildlaufleisten auswirken sollte.

Um ein solches Verhalten zu erreichen, bediente ich mich bei Microsoft. Auf dieser Seite ist beschrieben, welche Berechnungsschritte durchgeführt werden müssen, damit die Bildlaufleisten die korrekte Länge haben, sprich, dass man nicht zu weit oder zu kurz scrollt und das gesamte Bild gezeigt werden kann. Dazu muss die Bildgröße sowie der verfügbare Platz bekannt sein. Bei den Werten SmallChange und LargeChange handelt es sich um Schrittweiten, die beispielsweise beim Klick auf die Pfeile benötigt werden – beide werden anhand der Bildgröße berechnet.

scrollBarHor.SmallChange = image.Width / 20;
scrollBarHor.LargeChange = image.Width / 10;
scrollBarHor.Maximum = image.Width - usedArea.Width;
scrollBarHor.Maximum += (scrollBarHor.LargeChange - 1);

Mein Problem war nun jedoch, dass die Bildlaufleisten immer ein Stück zu viel zeigen wollten, das Bild war längst vorbei. Das kann man nun als Feature verkaufen, oder man lässt es. Ich wollte es lassen und suchte den Fehler, verglich immer wieder mit dem Quellcode von Microsoft, aber anscheinend war der Fehler nicht dort, es schien alles zu stimmen. Irgendwann stellte ich jedoch fest, dass die Werte für LargeChange und SmallChange im Debug-Modus merkwürdig waren. Lange dachte ich dann, dass es sich um einen Fehler im Debug-Modus handelt, dass die Werte eigentlich korrekt berechnet wurden (was hin und wieder auch der Fall war).

Doch der Fehler verbarg sich genau an der Stelle! SmallChange und LargeChange veränderten sich immer wieder und zwar genau dann, wenn ich das Maximum einer Bildlaufleiste berechnen wollte. Zunächst wurde LargeChange sehr klein, um anschließend wieder größer zu werden, und zwar genau an der Stelle, an der ich das Maximum zum ersten Mal veränderte (was ich in 2 Zeilen tue). Dadurch war in der zweiten Zeile der hier benötigte Wert LargeChange jedoch ein Falscher, weshalb mein Maximum immer wieder falsch berechnet wurde. Es schien also eine interne Kontrolle zu geben, die den Wert in Abhängigkeit vom Maximum änderte – mit fatalen Folgen.

Nun ja, die Lösung war jedenfalls simpel. Ich kopierte den Wert für LargeChange in eine zusätzliche Variable und konnte diese dann für die Berechnung des Maximums verwenden.

int lc = image.Width / 10;
scrollBarHor.LargeChange = lc;
scrollBarHor.Maximum += (lc - 1); // richtig
scrollBarHor.Maximum += (scrollBarHor.LargeChange - 1); // falsch

Im Anschluss ärgert man sich, dass man so lange für eine so simple Lösung gebraucht hat, aber ich bin froh, sie überhaupt gefunden zu haben. Und falls ihr den Fehler auch habt, so hoffe ich, dass ich helfen konnte. Solltet ihr jedoch feststellen, dass ich irgendwo diese Abhängigkeit erst verursacht habe, so bitte ich um einen Hinweis 😉

Viel Spaß beim Programmieren!


Teile diesen Beitrag

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert