如何阻止 Winforms 面板滚动?

发布于 2024-07-11 12:46:59 字数 340 浏览 6 评论 0原文

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

它不仅仅是一个 DataGridView;它也是一个 DataGridView。 任何高于面板的控件都会发生这种情况,例如 Infragistics UltraWinGrid、富文本框。 我将其作为 Infragistics 的错误提出,但他们说这是 Microsoft 的问题。

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

有什么建议么?

If you put a DataGridView that is 400 pixels high on a panel that's 300 pixels high, so that there's a scroll bar on the panel, then scroll down so that the lower half of the grid is shown, then click on a control outside the panel, then click on a line in the grid, the panel scrolls up to the top and the wrong row in the grid is selected.

It's not just a DataGridView; it happens with any control that's higher than the panel, eg Infragistics UltraWinGrid, Rich Text Box. I raised it as a bug with Infragistics, but they say it's a Microsoft issue.

I've tried using all the relevant events for the controls, but the Panel scroll happens before the events fire.

Any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

悲欢浪云 2024-07-18 12:46:59

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

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

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

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

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.

情绪失控 2024-07-18 12:46:59

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

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

比如:

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

这是我的新经历,我必须重新创造它。 我可能需要在我的网站上添加一篇关于它的文章:-)

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

所谓喜欢 2024-07-18 12:46:59

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

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

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

舂唻埖巳落 2024-07-18 12:46:59

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

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文