Laden...

Control in Panel - Autoscroll - Scrollen des Controls mit Fokus in den sichtbaren Bereich verhindern

Erstellt von snoop83 vor 14 Jahren Letzter Beitrag vor 14 Jahren 3.738 Views
S
snoop83 Themenstarter:in
46 Beiträge seit 2006
vor 14 Jahren
Control in Panel - Autoscroll - Scrollen des Controls mit Fokus in den sichtbaren Bereich verhindern

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?

S
snoop83 Themenstarter:in
46 Beiträge seit 2006
vor 14 Jahren

Anhang: Code-Example (Minimalbeispiel) zum experimentieren..

B
67 Beiträge seit 2009
vor 14 Jahren

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 ...

49.485 Beiträge seit 2005
vor 14 Jahren

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

S
snoop83 Themenstarter:in
46 Beiträge seit 2006
vor 14 Jahren

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.

B
67 Beiträge seit 2009
vor 14 Jahren

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 :\

S
1 Beiträge seit 2009
vor 14 Jahren

Hier wäre wohl die "saubere" Lösung:

Is your AutoScroll too auto?

Ist allerdings auch eher ein Hack als eine Lösung.

Hinweis von herbivore vor 10 Jahren

Bei dem Vorschlag werden die Nachrichten WM_VSCROLL = 0x115 und WM_HSCROLL 0x114 in der überschriebenen WndProc abgefangen, also nicht an base.WndProc weitergeleitet.

S
snoop83 Themenstarter:in
46 Beiträge seit 2006
vor 14 Jahren

Kennt noch jemand anderes eine Möglichkeit, das Problem zu umgehen?

Kann man die Scrollbalken irgendwie anders implementieren / nutzen?

S
snoop83 Themenstarter:in
46 Beiträge seit 2006
vor 14 Jahren

@ 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!

Hinweis von herbivore vor 10 Jahren

Eine Variante dieses Vorschlags findet sich in Automatisches Scrollen des Controls mit dem Fokus in den sichtbaren Bereich verhindern.

5.299 Beiträge seit 2008
vor 14 Jahren

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.