强制在ListView中显示滚动条?

时间:2016-08-20 19:08:15

标签: c# winforms listview pinvoke scrollbars

  • 背景:我们大多数人都知道 .NET Framework提供的SysListView32公共控件和等效包装器ListView。它内部的一点深度表明它滚动内容的滚动条是 NOT 控制自己,但是由{{{ 1}}控制。

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

    What I want...

  • 问题

    1. .NET ListBox内的滚动条完全 NO sugar 。< / LI>
    2. Win32文档未说明何时显示/隐藏和/或启用/禁用滚动条。
  • 我的解决方法

    1. ListView派生类中的override,并根据步骤2和3处理其WndProcWM_HSCROLL条消息。
    2. 调用WM_VSCROLL执行滚动功能的实际处理。
    3. 立即base.WndProc WmScroll创建after之类的方法并对其执行我的处理。
    4. 这包括对base.WndProc的p / invoke调用。确定是否确实需要滚动条。如果不是,请使用所需值调用GetScrollInfoShowScrollBar来绘制明显禁用的滚动条。
  • 解决方法问题

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

描述性图片:

This hides the beautiful collapse buttons (and looks awful)!

期待已久的实际问题

如何在 {{1>中强制滚动条总是 ListViewGroup 无论 Visible 的数量如何,如果不必要,则禁用它们,同时避免大小错误估算 (显示 ListView s) 的折叠按钮和主题恶化?

欢迎使用无代码的答案,以及 C# VB.NET C ++ / CLR 中的代码答案。如果您使用.NET支持的任何其他语言发布代码,请提供指向代码转换网站的链接,如果代码看起来很难理解,我可能会使用该代码转换网站。

1 个答案:

答案 0 :(得分:0)

  • <强>信息

    • 首先,我必须承认这是一个好的答案,而不是最好/最有效的答案。如果您有我的答案,请发布。
    • 其次,这个答案归功于Plutonixanswer,试验我默认ListView在其样式中没有WS_HSCROLL | WS_VSCROLL个标志。
      • 这就是为什么我之前的解决方法存在主题问题。
      • 这些经典滚动条是Windows提供给Control的没有设置这些标记的滚动条。
      • 更改CreateParams也不起作用。您必须使用OnHandleCreated。{/ li>在SetWindowLong方法中手动设置
      • 我发布的解决方案不使用上述技术。显然,为每个窗口消息调用ShowScrollBar会强制设置这些标志。
  • 解决方案

    • 定义您的WndProc,如下所示:

      protected override void WndPoc(ref Message m)
      {
      //custom code before calling base.WndProc
      base.WndProc(ref m);
      //custom after base.WndProc returns
      WmScroll(); //VERY INEFFICIENT, called for each message :(
      }
      
    • 按如下方式定义WmScroll():

      protected virtual void WmScroll()
      {
      NativeMethods.ShowScrollBar(Handle, SB_BOTH, true);
      	
      //si.fMask = SIF_PAGE | SIF_RANGE <- initialized in .ctor
      	
      NativeMethods.GetScrollInfo(Handle, SB_HORZ, ref si);
      if(si.nMax < si.nPage)
      	NativeMethods.EnableScrollBar(Handle, SB_HORZ, ESB_DISABLE_BOTH);
      else
      	NativeMethods.EnableScrollBar(Handle, SB_HORZ, ESB_ENABLE_BOTH);
      NativeMethods.GetScrollInfo(Handle, SB_VERT, ref si);
      if(si.nMax < si.nPage)
      	NativeMethods.EnableScrollBar(Handle, SB_VERT, ESB_DISABLE_BOTH);
      else
      	NativeMethods.EnableScrollBar(Handle, SB_VERT, ESB_ENABLE_BOTH);
      }
      
    • 输出

现在,看起来像:

What I Have

这些是添加了另一个项目,其中包含水平滚动和工作ListViewGroup折叠按钮:

Long text left Long text right

  • 不完美是的
    • 如果群组折叠更改了有效文字宽度,则需要调用AutoResizeColumns,否则垂直滚动条会隐藏折叠按钮。