24

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

它不仅仅是一个 DataGridView;它发生在任何高于面板的控件上,例如 Infragistics UltraWinGrid、Rich Text Box。我将其作为 Infragistics 的错误提出,但他们说这是 Microsoft 的问题。

我已经尝试使用控件的所有相关事件,但面板滚动发生在事件触发之前。

有什么建议么?

4

4 回答 4

51

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

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

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

用此面板控件替换您的面板控件。完毕。

于 2009-05-26T20:33:49.373 回答
2

我猜您正在将面板的 AutoScroll 属性设置为 true。当您这样做时,切换应用程序会将滚动位置重置为零,并且面板会重置其位置。

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

就像是:

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

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

于 2009-01-07T18:00:44.330 回答
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;
    }
}

这仅在面板中只有一个控件时才有效(尽管我没有使用多个控件对其进行测试)。

于 2009-12-09T11:29:23.607 回答
0

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

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

于 2009-01-07T16:54:26.740 回答