我在没有正确答案的情况下搜索了万维网。
在我的Windows窗体应用程序中,我想更改属于FlowLayoutPanel的滚动条的宽度。
“自动”添加滚动条,因为“流布局面板”的内容比“窗体”大。
从我在网上发现的情况来看,这似乎很棘手。
有没有解决方案?
干杯!
答案 0 :(得分:17)
不,无法更改单个控件上显示的滚动条的宽度(尽管系统范围的设置会影响所有所有滚动条应用)。
丑陋的事实是低滚动条控制远比看起来复杂得多。基本上,FlowLayoutPanel
上的滚动条是由Windows本身(而不是.NET Framework)绘制的,因为WS_HSCROLL
和/或WS_VSCROLL
窗口样式是为后面的控件设置的。场景。 FlowLayoutPanel
不提供任何更改或修改这些内置滚动条绘制方式的工具。与WinForms中的其他更高级的修改不同,我们不能将这些消息发送到控件的窗口过程。更糟糕的是,滚动条是在FlowLayoutPanel
的非客户区域中绘制的,这意味着我们不能仅覆盖其Paint
事件并自己处理滚动条的绘制。
不幸的是,如果你真的想要自定义你的滚动条,你将不得不隐藏内置的滚动条并滚动自己的滚动条。它听起来并不像听起来那么困难,但是,如果你愿意的话。 CodeProject上的This article提供了一个很好的演练,可以创建自己的可换肤滚动条作为用户控件,并将其用作您选择的容器控件中的替换。
答案 1 :(得分:1)
Cody Gray's answer 100%正确,但我想在主题上添加更多参考资料。
Windows窗体创建滚动条的方式是使用window styles WS_HSCROLL
和WS_VSCROLL
。这些样式分别负责为给定的HWND
启用水平和垂直滚动条。 HWND
是"窗口" 的本机资源句柄,在.NET术语中对应于Control
。
从Windows API的角度思考,我们必须在创建HWND
时设置窗口样式。这是通过致电CreateWindow
,CreateWindowEx
或SetWindowLong
来完成的。当然,我们可能会开始考虑使用P/Invoke来帮助我们,但这将是一个很大的负担,因为这意味着我们需要从头开始重新实现Windows窗体。
幸运的是,Windows窗体公开了一个属性CreateParams
,可以覆盖该属性以指定其他Control
创建参数中的确切窗口样式。这个属性反过来由.NET框架使用,以便在HWND
实例化时可以使用适当的样式创建Control
。
替换滚动条的Windows API功能实际上比看起来更简单;然而,这并不明显(对我而言,无论如何,我不得不筛选.NET源来找到答案)。为此,我们必须选择适当的Control
继承来创建我们自己的自定义 ScrollableControl 。如果我们观察System.Windows.Forms.ScrollableControl
的源代码,我们会看到使用以下样式:
CreateParams cp = base.CreateParams;
if (HScroll || HorizontalScroll.Visible) {
cp.Style |= NativeMethods.WS_HSCROLL;
}
else {
cp.Style &= (~NativeMethods.WS_HSCROLL);
}
if (VScroll || VerticalScroll.Visible) {
cp.Style |= NativeMethods.WS_VSCROLL;
}
else {
cp.Style &= (~NativeMethods.WS_VSCROLL);
}
因此,简而言之,当我们从ScrollableControl
扩展时,将根据其内部逻辑启用本机水平和垂直滚动条。我们可以访问ScrollableControl
窗口句柄,然后调用SetWindowLong
隐藏滚动条;但是,我们需要跟踪ScrollableControl
与Windows API交互的所有位置。实际上,根据是否应显示滚动条,调用内部函数Control.UpdateStylesCore()
。这个功能有效地重新应用了上面的窗口样式,最好不要与之抗争。这将是一种更加清晰的方法,可以避开Windows API并直接从Control
扩展。然后我们可以提供我们想要的任何API。
这意味着我们将考虑重新实施:
或者,一种简单的方法可能是创建一个新的UserControl
。这将允许我们使用Visual Studio设计器来简化滚动条按钮和轨道的配置。
无论采用哪种方式,都需要了解ScrollableControl
内部的工作原理,以便提供舒适的用户体验。
答案 2 :(得分:0)
对于C#而言,这与Cody Gray https://stackoverflow.com/a/4326046/4342139发表在“接受的答案”中的文章有关。我会在那里直接发表评论,但我为此欠缺声誉。
如果您和我一样,并按照科迪·格雷的回答写这篇文章,那么要隐藏滚动条,请使用内部和外部面板。这不是一个最佳的解决方案,坦率地说是“怪异和hacky”。我偶然发现了水平滚动条的类似问题,并设法找到了解决方案,同样的事情也适用于垂直滚动。这是一种不太hacky的方式(但不是很多),可以通过以下代码实现:
panel1.AutoScroll = false;
panel1.VerticalScroll.Maximum = 0;
panel1.VerticalScroll.Visible = false;
panel1.HorizontalScroll.Maximum = 0;
panel1.HorizontalScroll.Visible = false;
panel1.AutoScroll = true;
注意:从上面的代码中选择“垂直”或“水平”或两者。 将AutoScroll设置为false,然后再设置为true是至关重要的,否则将不应用设置或禁用AutoScroll。 将“垂直/水平滚动最大值”设置为0似乎只是需要做的事情,但是将Visible设置为false似乎并不会对它造成伤害(似乎根本不起作用,但也许我遗漏了一些东西)。