Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否强制在ListView中显示滚动条?_C#_Winforms_Listview_Pinvoke_Scrollbars - Fatal编程技术网

C# 是否强制在ListView中显示滚动条?

C# 是否强制在ListView中显示滚动条?,c#,winforms,listview,pinvoke,scrollbars,C#,Winforms,Listview,Pinvoke,Scrollbars,背景:我们大多数人都知道.NET Framework提供的SysListView32公共控件和等价的包装器ListView类。稍微深入了解一下它的内部结构,就会发现它为滚动其内容提供的滚动条不是控件本身,而是由SysListView32控件管理的 目标:始终绘制滚动条,即使它没有要显示的列表视图项,或者滚动条很少,因此不需要滚动条;有点像模仿RichTextBox类,其滚动条属性设置为ForcedBoth。或者类似这样的列表框: 问题: .NET对于列表视图中的滚动条,根本没有糖 W

背景:我们大多数人都知道.NET Framework提供的
SysListView32
公共控件和等价的包装器
ListView
类。稍微深入了解一下它的内部结构,就会发现它为滚动其内容提供的滚动条不是控件本身,而是由
SysListView32
控件管理的

  • 目标:始终绘制滚动条,即使它没有要显示的
    列表视图项
    ,或者滚动条很少,因此不需要滚动条;有点像模仿
    RichTextBox
    类,其
    滚动条
    属性设置为
    ForcedBoth
    。或者类似这样的
    列表框


    • 问题

    • .NET对于
      列表视图中的滚动条
      ,根本没有糖
    • Win32文档没有说明何时显示/隐藏和/或启用/禁用滚动条
    • 我的解决方案

    • 重写派生类中的
      WndProc
      ,并按照步骤2和3处理其
      WM\u HSCROLL
      WM\u VSCROLL
      消息
    • 调用
      base.WndProc
      对滚动功能执行实际需要的处理
    • 创建一个类似于
      WmScroll
      的方法,并在
      base.WndProc
      返回后立即对其进行
      处理
    • 这包括对
      GetScrollInfo
      的p/invoke调用。确定是否确实需要滚动条。如果没有,则使用所需值调用
      showcollbar
      enableCollbar
      ,以绘制明显禁用的滚动条
    • 解决方法的问题

    • 它几乎不起作用。滚动条显示和禁用,但与Windows经典主题下的滚动条类似
    • 它隐藏了每个
      列表视图组的折叠按钮,使它们毫无用处
      
    描述性图像:


    期待已久的实际问题

    如何强制滚动条在
    列表视图
    中始终可见
    ,而不考虑
    列表视图项的数量
    ,并在不需要滚动条时禁用滚动条,同时避免大小计算错误(显示
    列表视图组的折叠按钮)和主题退化?

    不带代码的答案,以及在C#VB.NETC++/CLR中带代码的答案都是受欢迎的。如果您使用.NET支持的任何其他语言发布代码,请同时留下一个链接,指向代码转换网站,如果代码看起来,呃,不可理解,我可能会使用该网站。

      信息

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

      • 定义您的
        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 :( } 受保护的覆盖无效WndPoc(参考消息m) { //调用base.WndProc之前的自定义代码 基准WndProc(参考m); //base.WndProc返回后的自定义 WmScroll();//效率很低,为每条消息调用:( }
      • 定义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); } 受保护的虚拟卷 { 显示滚动条(Handle、SB_和true); //si.fMask=SIF_页面| SIF_范围
        • 信息

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

          • 定义您的
            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 :( } 受保护的覆盖无效WndPoc(参考消息m) { //调用base.WndProc之前的自定义代码 基准WndProc(参考m); //base.WndProc返回后的自定义 WmScroll();//效率很低,为每条消息调用:( }
          • 定义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); } 受保护的虚拟卷 { 显示滚动条(Handle、SB_和true);
            //si.fMask=SIF_PAGE | SIF_RANGE显示了一系列与ListView相关的滚动条操作,包括指向
            ShowScrollBar
            @puropoix尼斯链接的Pinvoke,但我没有