How can you stop a Winforms Panel from scrolling?

限于喜欢 提交于 2019-12-03 09:43:54

I am guessing that you are setting the AutoScroll property of the panel to true. When you do so, switching applications resets the scroll position to zero and the panel resets its position.

If you switch off AutoScroll and add your own scrollbar you can set the scrollbar's maximum and minimum to match the requirements for the panel, then set the panel's scroll values in the Scroll event of the scrollbar. This is not reset when you switch windows.

Something like:

private void vScrollBar1_Scroll(object sender, ScrollEventArgs e)
{
    panel1.VerticalScroll.Value = vScrollBar1.Value;
}

This was a new one on me and I had to recreate it. I might have to add an article to my site about it :-)

This is caused by the ScrollToControl event being fired automatically by the ScrollableControl class, and the event handler scrolling to show the top left of the control that got focus. This behavior is not helpful when the scrollable container control only contains one control. I was very frustrated by this behavior until I found out how to stop it.

The way to stop this behavior is to override the ScrollToControl event handler, like this:

class PanelNoScrollOnFocus : Panel
{
    protected override System.Drawing.Point ScrollToControl(Control activeControl)
    {
        return DisplayRectangle.Location;
    }
}

Replace your panel control with this panel control. Done.

Sander

Thanks skypecakes, that worked beautifully :) Here's an edited version of your control that also keeps track of where the scrollbars where:

class AutoScrollPanel : Panel
{
    public AutoScrollPanel()
    {
        Enter += PanelNoScrollOnFocus_Enter;
        Leave += PanelNoScrollOnFocus_Leave;
    }

    private System.Drawing.Point scrollLocation;

    void PanelNoScrollOnFocus_Enter(object sender, System.EventArgs e)
    {
        // Set the scroll location back when the control regains focus.
        HorizontalScroll.Value = scrollLocation.X;
        VerticalScroll.Value = scrollLocation.Y;
    }

    void PanelNoScrollOnFocus_Leave(object sender, System.EventArgs e)
    {
        // Remember the scroll location when the control loses focus.
        scrollLocation.X = HorizontalScroll.Value;
        scrollLocation.Y = VerticalScroll.Value;
    }

    protected override System.Drawing.Point ScrollToControl(Control activeControl)
    {
        // When there's only 1 control in the panel and the user clicks
        //  on it, .NET tries to scroll to the control. This invariably
        //  forces the panel to scroll up. This little hack prevents that.
        return DisplayRectangle.Location;
    }
}

This works only if there's just one control in the Panel (although I haven't tested it with more then one control).

I understand your pain, this has gotten me more than once.

If your DataGridView is the only thing in the panel, just set the Dock to Fill and let the DGV handle scrolling on it's own. I don't think it will do the jumping thing anymore. Otherwise, I guess you could just size it so it's less than the panel and let it do the scrolling on it's own.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!