如何阻止 Winforms 面板滚动?
Posted
技术标签:
【中文标题】如何阻止 Winforms 面板滚动?【英文标题】:How can you stop a Winforms Panel from scrolling? 【发布时间】:2010-09-30 00:07:35 【问题描述】:如果您将一个 400 像素高的 DataGridView 放在一个 300 像素高的面板上,这样面板上就会有一个滚动条,然后向下滚动以显示网格的下半部分,然后单击一个控件在面板外,然后单击网格中的一行,面板向上滚动到顶部并选择了网格中的错误行。
它不仅仅是一个 DataGridView;它发生在任何高于面板的控件上,例如 Infragistics UltraWinGrid、Rich Text Box。我将其作为 Infragistics 的错误提出,但他们说这是 Microsoft 的问题。
我已尝试使用控件的所有相关事件,但面板滚动发生在事件触发之前。
有什么建议吗?
【问题讨论】:
【参考方案1】:我理解你的痛苦,这让我不止一次。
如果您的 DataGridView 是面板中唯一的内容,只需将 Dock 设置为 Fill 并让 DGV 自行处理滚动。我认为它不会再做跳跃的事情了。否则,我想你可以调整它的大小,让它小于面板,让它自己滚动。
【讨论】:
【参考方案2】:我猜您正在将面板的 AutoScroll 属性设置为 true。当您这样做时,切换应用程序会将滚动位置重置为零,并且面板会重置其位置。
如果您关闭 AutoScroll 并添加自己的滚动条,您可以设置滚动条的最大值和最小值以匹配面板的要求,然后在滚动条的 Scroll 事件中设置面板的滚动值。切换窗口时不会重置。
类似:
private void vScrollBar1_Scroll(object sender, ScrollEventArgs e)
panel1.VerticalScroll.Value = vScrollBar1.Value;
这对我来说是一个新的,我不得不重新创建它。我可能需要在我的网站上添加一篇关于它的文章 :-)
【讨论】:
谢谢你 - 它看起来很有希望。我们在使用 VScrollBar 时遇到了一些闪烁问题,但我相信我们可以想出一些可行的方法。它肯定会停止原来的跳跃问题。【参考方案3】:这是由于 ScrollToControl 事件由 ScrollableControl 类自动触发,并且事件处理程序滚动以显示获得焦点的控件的左上角。当可滚动容器控件仅包含一个控件时,此行为没有帮助。我对这种行为感到非常沮丧,直到我找到了阻止它的方法。
停止这种行为的方法是重写 ScrollToControl 事件处理程序,如下所示:
class PanelNoScrollOnFocus : Panel
protected override System.Drawing.Point ScrollToControl(Control activeControl)
return DisplayRectangle.Location;
用此面板控件替换您的面板控件。 完成。
【讨论】:
谢谢,过去一个小时我的头一直在桌子上。您的解决方案节省了去医院的行程! :) 谢谢!这是我需要的解决方案。 我该如何实现这个? 首先,将此类添加到您的项目中。 (创建一个新的空类文件并粘贴上面的代码。)然后转到表单设计器并查看工具箱。您现在应该会在此处看到一个新控件 PanelNoScrollOnFocus。将其拖到画布上;使用它作为您的面板,而不是使用香草面板。要更改现有表单,请手动编辑 .designer.cs 文件;搜索“System.Windows.Forms.Panel”并将其替换为 PanelNoScrollOnFocus 用于您想要此行为的每个面板。 完美的解决方案,而且代码很少。【参考方案4】:感谢 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;
这只有在面板中只有一个控件时才有效(尽管我没有测试过不止一个控件)。
【讨论】:
以上是关于如何阻止 Winforms 面板滚动?的主要内容,如果未能解决你的问题,请参考以下文章