I am creating an image browser that uses a FlowLayoutPanel
to display thumbnails of images. See animated GIF that shows how I scroll down the panel, switch to another window, and then back to the form which causes the FlowLayoutPanel
to scroll back to the top. I can't imagine any reason why it would do this.
Also, I seem to be able set the scroll location by clicking on the panel. When the form loses and regains focus, it scrolls back to the last Y position that I clicked.
Why is it exhibiting this behavior and how can I prevent it from occurring?
The effect described is quite common: when a FlowLayoutPanel contains Controls that can be activated and one of these child Controls is selected at some point (in this case a UserControl, which has the WS_EX_CONTROLPARENT
extended style, so SetStyle(ControlStyles.Selectable, false) won't do much) and the FlowLayoutPanel is then scrolled to hide this Control, when the Form is deactivated and then activated again, the ActiveControl is scrolled into view.
This causes the FlowLayoutPanel to scroll to a position where the child ActiveControl is visible.
▶ This doesn't happen when the child Controls are not selectable, as the PictureBox Control, for example. If this Control were used to present the thumbnails (as shown in the question), the FlowLayoutPanel would not scroll.
I think the simplest way to prevent the FlowLayoutPanel from scrolling to the ActiveControl is to set the FlowLayoutPanel itself as the ActiveControl when the Form is deactivated, handling the Deactivate event.
private void form1_Deactivate(object sender, EventArgs e)
{
this.ActiveControl = this.flowLayoutPanel1;
}
This has no meaningful side affects, except the Control that previously was the ActiveControl will raise the Leave
event.
It may be also used to suspend some other activity, since the User is now focusing on another Window.
▶ To set the ActiveControl to the default one instead (the Control that is activated when the Form is first shown), set this.ActiveControl = null;
. It will be reset when the Form is activated again.
I've seen sometimes the Activated
and Deactivate
events used to disable and enable back a ContainerControl: this also prevents the scrolling, of course, but may cause unwanted cascading effects when child Controls are disabled.
But it may also be something expected and possibly desired. It depends on what happens behind the scene (implementation details).
The solution proposed by @Loathing in comments can also work, deriving a Custom Control from FlowLayoutPanel. It depends on the use case.
Stop form from scrolling when moving controls