【问题标题】:How to disable horizontal scrollbar for table panel in winforms如何在winforms中禁用表格面板的水平滚动条
【发布时间】:2011-01-12 22:30:13
【问题描述】:

您好,我有一个 tablelayoutpanel,我正在动态地将控件绑定到它。当项目数超过面板的高度时,明显出现垂直滚动条没有问题。

但同时水平滚动条也会出现,即使项目宽度小于面板宽度。我怎样才能防止这种情况发生?

【问题讨论】:

  • 我意识到这已经 4 岁了,但是,我今天遇到了同样的问题(或非常相似的问题,修复就像 AutoScroll = false 一样简单,希望这对某人有所帮助!
  • @cullub AutoScroll = false 也会禁用垂直滚动条,但问题是如何只禁用水平滚动条

标签: c# winforms scrollbar tablelayout


【解决方案1】:

我知道这个问题已经很久了。但可能其他人可能会从对我有用的解决方案中受益。

诀窍在于,如果 auto scroll 属性为 true,则禁用水平滚动条不会执行任何操作。因此,只需禁用自动滚动,禁用水平滚动条,然后再次将自动滚动切换为 true。这对我有用。

只需将以下代码添加到构造函数或表单加载事件等位置即可。

tableLayoutPanel1.AutoScroll = false;
tableLayoutPanel1.HorizontalScroll.Enabled = false;
tableLayoutPanel1.AutoScroll = true;

【讨论】:

    【解决方案2】:

    这些解决方案都不适用于每种情况;我最终需要它们的组合:

    public void hideHorizontalScrollBar(ref TableLayoutPanel pan)
    {
        if (!pan.HorizontalScroll.Visible)
            return;
        pan.Padding = new Padding(0, 0, 0, 0);
        while (!!pan.HorizontalScroll.Visible || pan.Padding.Right >= SystemInformation.VerticalScrollBarWidth * 2)
        pan.Padding = new Padding(0, 0, pan.Padding.Right + 1, 0);
    }
    

    重要提示:可以在表单加载时调用一次,但也必须在布局调整大小事件中调用。

    【讨论】:

      【解决方案3】:

      我通过使用反射找到了一个完美的解决方案。 您可以尝试以下代码:

      static MethodInfo funcSetVisibleScrollbars;
      static EventHandler ehResized;
      
      public static void DisableHorizontalScrollBar(this ScrollableControl ctrl)
      {
           //cache the method info
           if(funcSetVisibleScrollbars == null)
           {
                 funcSetVisibleScrollbars = typeof(ScrollableControl).GetMethod("SetVisibleScrollbars",
                      BindingFlags.Instance | BindingFlags.NonPublic);
           }
      
           //init the resize event handler
           if(ehResized == null)
           {
                 ehResized = (s, e) =>
                 {
                      funcSetVisibleScrollbars.Invoke(s, new object[] { false, (s as ScrollableControl).VerticalScroll.Visible });
                 };
           }
      
           ctrl.Resize -= ehResized;
           ctrl.Resize += ehResized;
      }
      

      【讨论】:

        【解决方案4】:

        我通过使用一个简单的面板解决了这个问题,我将 tablelayoutpanel 停靠在该面板中。 然后我没有让 TLP 有滚动条,而是让面板。这对我来说很好。

        我假设具有不同列和行的 TLP 在计算每个列和行的宽度时存在问题,因此即使在不需要时也会显示垂直滚动条。

        【讨论】:

          【解决方案5】:

          我遇到过这个问题。

          很多人在 Datagrid 中也遇到同样的问题。但是,这个问题没有确切的解决方案,您必须根据使用情况手动确定面板的尺寸。

          tableLayoutPanel1.HorizontalScroll.Enabled = false;
          

          这将禁用水平滚动条,但您必须手动调整表格布局面板的尺寸。

          另一种方法是在运行时计算 tablelayoutpanel 的可能宽度,如果它大于您设置的值,则可以启用它。

          tableLayoutPanel1.HorizontalScroll.Enabled = true;
          

          【讨论】:

          • 不起作用。水平滚动条与以前一样出现。备用 Visible 属性也不起作用。
          【解决方案6】:

          这在 .NET 3.5 中完美运行,而其他解决方案并没有完全提供我想要的:

            if (this.TableLayoutPanel1.HorizontalScroll.Visible)
            {
              int newWid = this.TableLayoutPanel1.Width -
                            (2 * SystemInformation.VerticalScrollBarWidth);
              //this.TableLayoutPanel1.Padding = new Padding(0, 0, newWid, 0);
              foreach (Control ctl in this.TableLayoutPanel1.Controls)
              {
                ctl.Width = newWid;
              }
            }
          

          【讨论】:

            【解决方案7】:

            我有一个停靠的 TableLayoutPanel 包含停靠的 GroupBoxes 和设置为 100% 宽度的单个列的问题。我不想为这些设置手动大小 - 我希望它们与表单一起调整大小。

            奇怪的是,将 TableLayoutPanel 的 Right Padding 设置为 1(不是滚动条的宽度 - 如您所料,这会留下滚动条大小的间隙)完全解决了这个问题。这是在 C# 2010 Express、.NET 4、Windows 8 中。不知道这个 kludge 是否适用于其他变体。

            将padding设置为0貌似解决了IDE中的问题,但实际运行时问题依旧存在。

            在我看来,TableLayoutPanel 中存在某种错误……或者可能只是我拥有的控件和属性的特定组合(这是一个非常复杂的布局)。

            【讨论】:

            • 确认适用于 .NET 3.5、Windows 7
            • 已确认适用于 .NET 4.6.2、Windows 10。Visual Studio 2017。不过需要将 Padding 设置为 9px。 1 px 似乎只能解决编辑器中的问题。
            • 已确认适用于 .NET 3.5、Windows 7、SharpDevelop 4.4。但是我必须达到 6 像素才能使其工作
            • 谢谢,填充 1 适用于 .NET 4.5.1、Windows 10 和 2017。有趣
            • 必须添加第二条评论:今天我遇到了类似的情况,即 1px 的填充不起作用。但是 2px 做到了。所以尝试不同的值。
            【解决方案8】:

            今天掉了几根头发,但我解决了它,这就是我最终的结果:

            1. 创建一个继承自 TableLayoutPanel 的新类(我们称之为 MyTableLayoutPanel),并像这样覆盖 MaximumSize 属性:

              public override Size MaximumSize
              {
                  get
                  {
                      if (Parent != null)
                          return new Size(Parent.Width, 0);
                      else
                          return base.MaximumSize;
                  }
                  set
                  {
                      base.MaximumSize = value;
                  }
              }
              

              当然,您可以通过添加另一个属性来决定您是否应该返回更改后的 MaximumSize,从而使其更通用,但希望这对阅读本文的任何人来说都是显而易见的。

            2. 将您拥有的 TableLayoutPanel 更改为新的 MyTableLayoutPanel 类型。

            3. 将其添加到常规面板。在此面板上启用 AutoScroll 而不是 MyTableLayoutPanel(如果您还没有,请在此处禁用它)。

            4. 将 MyTableLayoutPanel AutoSize 属性设置为 true,并将其 Anchor 属性设置为 Left、Right 和 Top。

            【讨论】:

            • 这是唯一真正适合我的布局的解决方案,谢谢!
            【解决方案9】:
            int vertScrollWidth = SystemInformation.VerticalScrollBarWidth;
            
            tableLayoutPanel1.Padding = new Padding(0, 0, vertScrollWidth, 0);
            

            【讨论】:

            • 有趣的解决方案。你有没有机会知道为什么这个魔法会起作用?
            • 在 .NET 4.6.2 上对此进行了测试。当高度不够时,它确实会删除 h-scroll bar,但问题是它会在右侧产生很大的边距,当 v-scroll bar 出现时它不会消失。我希望 TableLayoutPanel 填充窗口宽度。
            • 我们把这段代码放在哪里?在我们表单类的构造函数中?还是在哪里?
            【解决方案10】:

            问题是您的项目恰好是布局面板的宽度,因此当垂直滚动出现时它会切入您的控件,从而强制水平滚动?如果是这样,您可以将控件宽度缩小以考虑滚动条的可能性,或者您可以在滚动条出现时尝试调整它们。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2014-06-16
              • 2011-03-28
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-01-13
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多