如何阻止Winforms面板滚动?

时间:2009-01-07 09:50:17

标签: .net winforms panel

如果在300像素高的面板上放置一个400像素高的DataGridView,那么面板上会有一个滚动条,然后向下滚动以显示网格的下半部分,然后单击一个控件在面板外部,然后单击网格中的一条线,面板向上滚动到顶部,并选择网格中的错误行。

它不仅仅是一个DataGridView;它发生在任何高于面板的控件上,例如Infragistics UltraWinGrid,Rich Text Box。我把它作为Infragistics的一个bug提出来了,但是他们说这是微软的问题。

我已尝试将所有相关事件用于控件,但Panel事件在事件触发前发生。

有什么建议吗?

4 个答案:

答案 0 :(得分:44)

这是由ScrollableControl类自动触发ScrollToControl事件引起的,并且事件处理程序滚动显示控件左上角的焦点。当可滚动容器控件仅包含一个控件时,此行为没有帮助。我对这种行为感到非常沮丧,直到我发现如何阻止它。

停止此行为的方法是覆盖ScrollToControl事件处理程序,如下所示:

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

使用此面板控件替换面板控件。 完成。

答案 1 :(得分:2)

我猜您正在将面板的AutoScroll属性设置为true。执行此操作时,切换应用程序会将滚动位置重置为零,并且面板将重置其位置。

如果您关闭AutoScroll并添加自己的滚动条,您可以设置滚动条的最大值和最小值以匹配面板的要求,然后在滚动条的滚动事件中设置面板的滚动值。切换窗口时不会重置此项。

类似的东西:

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

这对我来说是一个新的,我不得不重新创建它。我可能要在我的网站上添加一篇关于它的文章: - )

答案 2 :(得分:1)

感谢skypecakes,它工作得很漂亮:)这是你的控件的编辑版本,它也跟踪滚动条在哪里:

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;
    }
}

仅当Panel中只有一个控件时才有效(虽然我没有用多个控件测试它)。

答案 3 :(得分:0)

我理解你的痛苦,这让我不止一次。

如果您的DataGridView是面板中唯一的东西,只需将Dock设置为Fill并让DGV手柄自行滚动。我不认为它会再做跳跃的事情了。否则,我想你可以调整它的大小,使它比面板小,让它自己滚动。