强制在ListView中显示滚动条?
-
背景知识 :我们大多数人都知道
SysListView32
公共控件和.NET Framework提供的等效包装器ListView
类。 它内部的一点深度表明,它为滚动内容提供的滚动条不是控件本身,而是由SysListView32
控件管理。 -
目标 :总是绘制滚动条,即使它没有要显示的
ListViewItems
,或者只有很少的滚动条,无论如何都不需要滚动条; 有点像模仿RichTextBox
类,其ScrollBars
属性设置为ForcedBoth
。 或者有点像这个ListBox
:
-
问题 :
- 对于
ListView
滚动条, .NET完全没有糖。 - Win32文档未说明何时显示/隐藏和/或启用/禁用滚动条。
- 对于
-
我的解决方法 :
-
override
派生类中的WndProc
并按照步骤2和3处理其WM_HSCROLL
和WM_VSCROLL
消息。 - 调用
base.WndProc
来执行滚动function的实际所需处理。 - 创建一个类似
WmScroll
的方法,并after
base.WndProc
返回after
立即对其after
处理。 - 这包括对
GetScrollInfo
的ap / invoke调用。 确定是否确实需要滚动条。 如果不是,则调用ShowScrollBar
和EnableScrollBar
,并使用所需的值绘制明显禁用的滚动条。
-
-
解决方法的问题 :
- 它几乎没有用。 滚动条显示和禁用,但与Windows经典主题下的滚动条类似。
- 它隐藏了每个
ListViewGroup
的折叠按钮,使它们无用!
描述性图片:
期待已久的实际问题 :
如何强制滚动条 在 ListView
始终 Visible
, 而不管 ListView
的数量如何, 如果不需要它们,则禁用它们,同时避免大小错误计算 (显示 ListViewGroup
的 折叠按钮 ) 和主题恶化?
没有代码的答案,以及C# , VB.NET和C ++ / CLR中的代码答案都是受欢迎的。 如果您使用.NET支持的任何其他语言发布代码,请提供指向代码转换网站的链接,如果代码看似呃,不可理解,我可以使用。
-
信息 :
- 首先,我必须承认这是一个好的答案,而不是最好/最有效的答案。 如果您有我的答案,请发布。
- 其次,这个答案归功于Plutonix的答案 ,试验我默认
ListView
没有WS_HSCROLL | WS_VSCROLL
WS_HSCROLL | WS_VSCROLL
标志在其样式中设置。- 这就是为什么我之前的解决方法存在主题问题。
- 这些经典滚动条是Windows为
Control
s提供的,没有设置这些标志。 - 更改
CreateParams
也不起作用。 您必须使用SetWindowLong
在OnHandleCreated
方法中手动设置它。 - 我发布的解决方案不使用上述技术。 显然,为每个窗口消息调用
ShowScrollBar
强制设置这些标志。
-
解决方案 :
-
像下面这样定义您的
WndProc
:protected override void WndPoc(ref message m) { //在调用base.WndProc之前自定义代码 base.WndProc(ref m); //在base.WndProc返回后自定义 WmScroll(); //非常缺乏,呼吁每条消息:( }
-
定义WmScroll()如下:
protected virtual void WmScroll() { NativeMethods.ShowScrollBar(Handle,SB_BOTH,true); //si.fMask = SIF_PAGE | SIF_RANGE < - 在.ctor中初始化 NativeMethods.GetScrollInfo(Handle,SB_HORZ,ref si); if(si.nMax
- 输出 :
-
它现在,看起来像:
这些是添加了另一个项目,具有水平滚动和工作ListViewGroup
折叠按钮:
- 不完美 , 是的,有 :
- 如果组折叠更改了有效文本宽度,则需要调用
AutoResizeColumns
,否则垂直滚动条会隐藏折叠按钮。
- 如果组折叠更改了有效文本宽度,则需要调用