强制在ListView中显示滚动条?

  • 背景知识 :我们大多数人都知道SysListView32公共控件和.NET Framework提供的等效包装器ListView类。 它内部的一点深度表明,它为滚动内容提供的滚动条不是控件本身,而是由SysListView32控件管理。

  • 目标 :总是绘制滚动条,即使它没有要显示的ListViewItems ,或者只有很少的滚动条,无论如何都不需要滚动条; 有点像模仿RichTextBox类,其ScrollBars属性设置为ForcedBoth 。 或者有点像这个ListBox

    我想要的是...


  • 问题

    1. 对于ListView滚动条, .NET完全没有糖。
    2. Win32文档未说明何时显示/隐藏和/或启用/禁用滚动条。
  • 我的解决方法

    1. override派生类中的WndProc并按照步骤2和3处理其WM_HSCROLLWM_VSCROLL消息。
    2. 调用base.WndProc来执行滚动function的实际所需处理。
    3. 创建一个类似WmScroll的方法,并after base.WndProc返回after立即对其after处理。
    4. 这包括对GetScrollInfo的ap / invoke调用。 确定是否确实需要滚动条。 如果不是,则调用ShowScrollBarEnableScrollBar ,并使用所需的值绘制明显禁用的滚动条。
  • 解决方法的问题

    1. 它几乎没有用。 滚动条显示和禁用,但与Windows经典主题下的滚动条类似。
    2. 它隐藏了每个ListViewGroup的折叠按钮,使它们无用!

描述性图片:

这隐藏了漂亮的折叠按钮(看起来很糟糕)!


期待已久的实际问题

如何强制滚动条 ListView 始终 Visible 而不管 ListView 的数量如何, 如果不需要它们,则禁用它们,同时避免大小错误计算 (显示 ListViewGroup 折叠按钮 和主题恶化?

没有代码的答案,以及C#VB.NETC ++ / CLR中的代码答案都是受欢迎的。 如果您使用.NET支持的任何其他语言发布代码,请提供指向代码转换网站的链接,如果代码看似呃,不可理解,我可以使用。

  • 信息

    • 首先,我必须承认这是一个好的答案,而不是最好/最有效的答案。 如果您有我的答案,请发布。
    • 其次,这个答案归功于Plutonix的答案 ,试验我默认ListView没有WS_HSCROLL | WS_VSCROLL WS_HSCROLL | WS_VSCROLL标志在其样式中设置。
      • 这就是为什么我之前的解决方法存在主题问题。
      • 这些经典滚动条是Windows为Control s提供的,没有设置这些标志。
      • 更改CreateParams也不起作用。 您必须使用SetWindowLongOnHandleCreated方法中手动设置它。
      • 我发布的解决方案不使用上述技术。 显然,为每个窗口消息调用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 ,否则垂直滚动条会隐藏折叠按钮。