【问题标题】:Force the display of scroll bars in a ListView?强制在 ListView 中显示滚动条?
【发布时间】:2016-12-27 17:17:35
【问题描述】:
  • 背景:我们大多数人都知道 .NET Framework 提供的 SysListView32 通用控件和等效的包装器 ListView 类。深入了解其内部结构表明,它提供的用于滚动其内容的滚动条不是控件本身,而是由SysListView32 控件管理。

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


  • 问题

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

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

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

描述性图片:


期待已久的实际问题

我如何强制滚动条总是在 Visible 在一个 ListView 不管有多少个ListViewItems如果不需要就禁用它们,同时避免尺寸误算 (显示 ListViewGroups 的折叠按钮) 和主题恶化?

欢迎无代码回答,欢迎使用 C#VB.NETC++/CLR 中的代码回答。如果您以 .NET 支持的任何其他语言发布代码,还请留下一个代码转换网站的链接,如果代码看起来,呃,难以理解,我可能会使用。

【问题讨论】:

  • 有一堆 ListView 相关的滚动条操作显示in this Q+A 包括一个 Pinvoke 到 ShowScrollBar
  • @Plutonix 不错的链接,但我不想根据是否出现滚动条来调整列的大小。我也不想隐藏滚动条。我只希望他们在ListView 的整个生命周期中都存在。
  • 鉴于系统似乎不想这样做,并且列表视图以其标准形式完美运行,我想知道您的动机是什么。
  • @DavidHeffernan 除了看起来很酷之外,主要是学习——如果其他常见控件支持这一点,为什么不支持这个。我也喜欢在测试对象上做实验(在这种情况下是ListView),直到我碰壁说“这不可能!”或“这是邪恶的!”。 ;) 在这两种情况下,我只想知道为什么我不应该做一些我可能会尝试做的事情。
  • @DavidHeffernan 在这种情况下的动机:我不希望我的ListView 显示部分项目。启用水平滚动后,如果我相应地设置大小,则会显示整数个项目。这仅适用于显示的滚动条,或不显示但不能同时显示的滚动条(默认情况下根据需要显示它们)。我不想禁用水平滚动,也不能动态更改ListView 的大小(这太尴尬了。)所以,这是我唯一的选择:根据需要禁用和启用滚动条让它们在 ListView 的整个生命周期中可见。

标签: c# winforms listview pinvoke scrollbars


【解决方案1】:
  • 信息

    • 首先,我必须承认这是一个好的答案,而不是最好/最有效的答案。如果您的答案与我的不同,请发布。
    • 其次,这个答案归功于Plutonixanswer,通过实验我了解到默认情况下ListView 在其样式中没有设置WS_HSCROLL | WS_VSCROLL 标志。
      • 这就是我之前的解决方法在主题方面存在问题的原因。
      • 这些 Classic 滚动条是 Windows 提供给未设置这些标志的 Controls 的滚动条。
      • 更改CreateParams 也不起作用。您必须使用SetWindowLongOnHandleCreated 方法中手动设置它。
      • 我发布的解决方案没有使用上述技术。显然,为每个窗口消息调用 ShowScrollBar 会强制设置这些标志。
  • 解决方案

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

      受保护的覆盖无效 WndPoc(参考消息 m) { //调用base.WndProc之前的自定义代码 base.WndProc(参考 m); //base.WndProc返回后自定义 WmScroll(); //非常低效,每条消息都调用:( }
    • 如下定义WmScroll():

      受保护的虚拟 void WmScroll() { NativeMethods.ShowScrollBar(Handle, SB_BOTH, true); //si.fMask = SIF_PAGE | SIF_RANGE
    • 输出

现在,看起来像:

这些是添加了另一个具有水平滚动和工作ListViewGroup折叠按钮的项目:

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

【讨论】:

  • 因为我很快从您的帖子中复制了链接文本。
猜你喜欢
  • 2010-11-26
  • 1970-01-01
  • 2013-12-03
  • 2011-05-14
  • 1970-01-01
  • 2014-09-02
  • 2023-03-21
  • 2014-11-05
  • 2018-06-06
相关资源
最近更新 更多