Hallo,
ich habe mein Problem anhand eines Minimalbeispiels nachgebaut: Ich habe ein UserControl, welchen Zweck auch immer das erfüllt (meins soll zum Zeichnen von irgendwelchen Objekten dienen). Dieses UserControl ist auf einem Panel untergebracht, bei dem das AutoScroll-Property auf true gesetzt ist.
Mein Problem äußert sich nun wie folgt: Ich selektiere mein UserControl, arbeite damit und verschiebe in diesem Zusammenhang die Scrollbalken des Panels, auf dem das UserControl untergebracht ist. Wechsle ich nun mit dem Fokus aus dem UserControl z.B. in eine Textbox außerhalb des Panels und kehre anschließend zurück, so wird der Scrollstatus nicht erhalten.
Das ganze resultiert darin, dass ich bei jedem Verlassen des UserControls und zurückkehren wieder ganz oben bin, also erneut nach unten scrollen muss. Drei Bilder sollen das Problem verdeutlichen, siehe Anhang.
Kann mir jemand erklären, woran das liegt und wie ich das springen der Scrollbalken bei Fokuswechsel verhindern kann?
Anhang: Code-Example (Minimalbeispiel) zum experimentieren..
Ich schliesse mich dem Fragesteller an, mich interessiert auch warum der Scrollzustand bei einer Focusänderung nicht erhalten bleibt.
Ein Workaround wäre natürlich einfach klassisch die Scrollzustände zu speichern, sich ans Focus-Event zu hängen und die Scrollvalues explizit wieder auf ihre Ursprungswerte zu setzen.
Edit: In etwa so:
private void Panel_Leave(object sender, System.EventArgs e)
{
_horizontalScrollValue = HorizontalScroll.Value;
_verticalScrollValue = VerticalScroll.Value;
}
private void Panel_Enter(object sender, System.EventArgs e)
{
HorizontalScroll.Value = _horizontalScrollValue;
VerticalScroll.Value = _verticalScrollValue;
}
Funktioniert bei mir, befriedigt mich aber nicht ...
Hallo snoop83,
wenn ein Control auf einem AutoScroll-Panel den Focus bekommt, dann scrollt das Panel automatisch so, dass das Control sichtbar ist. Das ist ja meistens auch sinnvoll. Ist quasi "works as designed".
herbivore
Hallo Birne,
genau den Workaround bin ich nun auch erstmal gegangen. Leider äußert sich das bei mir allerdings so, dass die Scrollbalken danach nicht immer korrekt positioniert sind. Der Ausschnitt stimmt, aber die Scrollbalken scrollen teilweise nicht zum korrekten Offset.
Wenn ich es mit einer kurzen Verzögerung mache (Thread.Sleep() im Millisekundenbereich), habe ich ein unschönes Flackern, aber die Scrollbalken haben die korrekte Position.
Ich hoffe, es gibt noch eine bessre Lösung.
Hallo,
Und diesen Offset kannst du nicht irgendwie ermitteln und entsprechend korrigieren ?
Änderst du vllt. den Inhalt so das der Offset nicht mehr stimmt ?
Andernfalls ist mir auch keinr saubere Lösung bekannt :\
Hier wäre wohl die "saubere" Lösung:
Ist allerdings auch eher ein Hack als eine Lösung.
Bei dem Vorschlag werden die Nachrichten WM_VSCROLL = 0x115 und WM_HSCROLL 0x114 in der überschriebenen WndProc abgefangen, also nicht an base.WndProc weitergeleitet.
Kennt noch jemand anderes eine Möglichkeit, das Problem zu umgehen?
Kann man die Scrollbalken irgendwie anders implementieren / nutzen?
@ sp00k:
Super, der Einzeiler
protected override System.Drawing.Point ScrollToControl(Control activeControl)
{
return DisplayRectangle.Location;
}
erfüllt endlich die gewünschte Funktionalität, genau so etwas habe ich gesucht!!
Besten Dank!
Eine Variante dieses Vorschlags findet sich in Automatisches Scrollen des Controls mit dem Fokus in den sichtbaren Bereich verhindern.
Du kannst auch dein UserControl selbst scrollen lassen, indem du Autoscroll.true setzst und eine AutoScrollMinSize angibst.
Kann aber sein, dann mußt du deine Zeichnereien umstrukturieren, nämlich AutoscrollPosition einbeziehen.
Der frühe Apfel fängt den Wurm.