C# 为什么水平滚动条仍显示在此面板中?

C# 为什么水平滚动条仍显示在此面板中?,c#,winforms,C#,Winforms,我有一个面板,其中包含许多较小的面板。 包含面板的AutoScroll设置为true,这样当有太多小面板时,我可以向下滚动。 小面板的宽度始终设置为容器的clientsize宽度(允许边框等),因此不会显示水平滚动条。 这似乎是最常见的情况,除非最后一个子面板接触到包含面板的底部,然后水平滚动条在我不希望的时候出现 我试过了,但似乎没有效果。 我试过(因为这是可以接受的),但它只是短暂地显示了一个非常丑陋的酒吧,然后消失了,取而代之的是本地酒吧。 我能看到,但没有解决办法 将下面的代码粘贴到新的

我有一个
面板
,其中包含许多较小的面板。
包含面板的
AutoScroll
设置为true,这样当有太多小面板时,我可以向下滚动。
小面板的宽度始终设置为容器的clientsize宽度(允许边框等),因此不会显示水平滚动条。
这似乎是最常见的情况,除非最后一个子面板接触到包含面板的底部,然后水平滚动条在我不希望的时候出现

我试过了,但似乎没有效果。
我试过(因为这是可以接受的),但它只是短暂地显示了一个非常丑陋的酒吧,然后消失了,取而代之的是本地酒吧。
我能看到,但没有解决办法

将下面的代码粘贴到新的Winform中,然后尝试以下步骤:

  • 按下“添加”按钮4次以获得4个面板,它们应离开容器底部
  • 垂直调整窗体大小,以便在最后一个面板后有一些空白
  • 现在小心地垂直调整窗体的大小,使最后一个面板的底部接触容器的底部。滚动条应该出现在这附近,可能需要一些“摆动”

    static List<Panel> listOfPanels;
    static Panel panel;
    static bool flipflop;
    
    private void Form1_Load(object sender, EventArgs e)
    {
        Height = 400;
        Width = 400;
    
        listOfPanels = new List<Panel>();
    
        panel = new Panel()
        {
            Height = this.ClientSize.Height - 20,
            Width = 200,
            Top = 10,
            Left = 10,
            BackColor = Color.White,
            BorderStyle = BorderStyle.FixedSingle,
            Padding = Padding.Empty,
            Margin = Padding.Empty,
            Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Bottom,
        };
    
        // I'VE TRIED DISABLING IT HERE!
        panel.AutoScroll = false;
        panel.HorizontalScroll.Enabled = false;
        panel.HorizontalScroll.Visible = false;
        panel.AutoScroll = true;
    
        panel.Resize += panel_Resize;
    
        Button button = new Button()
        {
            Text = @"Add",
            Size = new Size(100, 50),
            Top = 10,
            Left = 20 + panel.Width
        };
        button.Click += button_Click;
    
        Controls.Add(panel);
        Controls.Add(button);
    }
    
    void panel_Resize(object sender, EventArgs e)
    {
        renderSubPanels();
    }
    
    void button_Click(object sender, EventArgs e)
    {
        Panel subPanel = new Panel()
        {
            Height = 100,
            BackColor = flipflop ? Color.PeachPuff : Color.PowderBlue,
            Top = (listOfPanels.Count * 100) - Math.Abs(panel.AutoScrollPosition.Y)
        };
    
        listOfPanels.Add(subPanel);
    
        flipflop = !flipflop;
    
        panel.Controls.Add(subPanel);
    
        renderSubPanels();
    }
    
    void renderSubPanels()
    {
        panel.SuspendLayout();
        bool verticalScrollVisible = listOfPanels.Count * 100 > panel.ClientSize.Height;
        foreach (Panel p in listOfPanels)
        {
            if (verticalScrollVisible)
            {
                p.Width = panel.Width - System.Windows.Forms.SystemInformation.VerticalScrollBarWidth - 2;
            }
            else
            {
                p.Width = panel.Width - 2;
            }
    
            p.Top = (listOfPanels.IndexOf(p) * 100) - Math.Abs(this.AutoScrollPosition.Y);
        }
        panel.ResumeLayout();
    }
    
    面板的静态列表;
    静态面板;
    静态布尔触发器;
    私有void Form1\u加载(对象发送方、事件参数e)
    {
    高度=400;
    宽度=400;
    listOfPanels=新列表();
    面板=新面板()
    {
    高度=this.ClientSize.Height-20,
    宽度=200,
    Top=10,
    左=10,
    背景色=颜色。白色,
    BorderStyle=BorderStyle.FixedSingle,
    Padding=Padding.Empty,
    边距=填充。空,
    锚点=锚点样式。顶部|锚点样式。左侧|锚点样式。底部,
    };
    //我试过在这里禁用它!
    panel.AutoScroll=false;
    panel.horizontalcoll.Enabled=false;
    panel.horizontalcoll.Visible=false;
    panel.AutoScroll=true;
    panel.Resize+=面板_Resize;
    按钮按钮=新按钮()
    {
    Text=@“添加”,
    尺寸=新尺寸(100,50),
    Top=10,
    左=20+面板。宽度
    };
    按钮。单击+=按钮\u单击;
    控件。添加(面板);
    控件。添加(按钮);
    }
    无效面板\调整大小(对象发送器、事件参数e)
    {
    渲染子面板();
    }
    无效按钮\单击(对象发送者,事件参数e)
    {
    面板子面板=新面板()
    {
    高度=100,
    BackColor=flipflop?Color.PeachPuff:Color.PowderBlue,
    Top=(listOfPanels.Count*100)-Math.Abs(panel.AutoScrollPosition.Y)
    };
    添加面板列表(子面板);
    触发器=!触发器;
    面板.控件.添加(子面板);
    渲染子面板();
    }
    void renderSubPanels()
    {
    panel.SuspendLayout();
    bool verticalScrollVisible=listOfPanels.Count*100>panel.ClientSize.Height;
    foreach(面板列表中的面板p)
    {
    如果(垂直滚动可见)
    {
    p、 宽度=面板宽度-System.Windows.Forms.SystemInformation.VerticalScrollBarWidth-2;
    }
    其他的
    {
    p、 宽度=面板。宽度-2;
    }
    p、 Top=(planels.IndexOf(p)*100)-Math.Abs(this.AutoScrollPosition.Y);
    }
    panel.resume布局();
    }
    
  • 在我真正的程序中,它实际上是一个我正在使用的自定义面板,所以我对想法持开放态度。我只想让这讨厌的东西走开

    谢谢

    注释掉自动滚动:

    //panel.AutoScroll = true;
    
    然后添加以下代码:

    panel.ControlAdded += panel_ControlAdded;
    
    void panel_ControlAdded(object sender, ControlEventArgs e) {
      panel.AutoScrollMinSize = new Size(0,
        panel.Controls.Cast<Control>().Sum(x => x.Height));
    }
    

    注释掉自动滚动:

    //panel.AutoScroll = true;
    
    然后添加以下代码:

    panel.ControlAdded += panel_ControlAdded;
    
    void panel_ControlAdded(object sender, ControlEventArgs e) {
      panel.AutoScrollMinSize = new Size(0,
        panel.Controls.Cast<Control>().Sum(x => x.Height));
    }
    

    注释掉自动滚动:

    //panel.AutoScroll = true;
    
    然后添加以下代码:

    panel.ControlAdded += panel_ControlAdded;
    
    void panel_ControlAdded(object sender, ControlEventArgs e) {
      panel.AutoScrollMinSize = new Size(0,
        panel.Controls.Cast<Control>().Sum(x => x.Height));
    }
    

    注释掉自动滚动:

    //panel.AutoScroll = true;
    
    然后添加以下代码:

    panel.ControlAdded += panel_ControlAdded;
    
    void panel_ControlAdded(object sender, ControlEventArgs e) {
      panel.AutoScrollMinSize = new Size(0,
        panel.Controls.Cast<Control>().Sum(x => x.Height));
    }
    

    我认为您可以通过使用
    面板来获得所需的行为。PerformLayout
    而不是
    SuspendLayout
    /
    ResumeLayout

        void renderSubPanels()
        {
            //panel.SuspendLayout();
            bool verticalScrollVisible = listOfPanels.Count * 100 > panel.ClientSize.Height;
            foreach (Panel p in listOfPanels)
            {
                if (verticalScrollVisible)
                {
                    p.Width = panel.Width - System.Windows.Forms.SystemInformation.VerticalScrollBarWidth - 2;
                }
                else
                {
                    p.Width = panel.Width - 2;
                }
    
                p.Top = (listOfPanels.IndexOf(p) * 100) - Math.Abs(this.AutoScrollPosition.Y);
            }
            //panel.ResumeLayout();
            panel.PerformLayout();
        }
    

    这似乎适合我。

    我认为您可以通过使用
    面板来获得所需的行为。PerformLayout
    而不是
    SuspendLayout
    /
    ResumeLayout

        void renderSubPanels()
        {
            //panel.SuspendLayout();
            bool verticalScrollVisible = listOfPanels.Count * 100 > panel.ClientSize.Height;
            foreach (Panel p in listOfPanels)
            {
                if (verticalScrollVisible)
                {
                    p.Width = panel.Width - System.Windows.Forms.SystemInformation.VerticalScrollBarWidth - 2;
                }
                else
                {
                    p.Width = panel.Width - 2;
                }
    
                p.Top = (listOfPanels.IndexOf(p) * 100) - Math.Abs(this.AutoScrollPosition.Y);
            }
            //panel.ResumeLayout();
            panel.PerformLayout();
        }
    

    这似乎适合我。

    我认为您可以通过使用
    面板来获得所需的行为。PerformLayout
    而不是
    SuspendLayout
    /
    ResumeLayout

        void renderSubPanels()
        {
            //panel.SuspendLayout();
            bool verticalScrollVisible = listOfPanels.Count * 100 > panel.ClientSize.Height;
            foreach (Panel p in listOfPanels)
            {
                if (verticalScrollVisible)
                {
                    p.Width = panel.Width - System.Windows.Forms.SystemInformation.VerticalScrollBarWidth - 2;
                }
                else
                {
                    p.Width = panel.Width - 2;
                }
    
                p.Top = (listOfPanels.IndexOf(p) * 100) - Math.Abs(this.AutoScrollPosition.Y);
            }
            //panel.ResumeLayout();
            panel.PerformLayout();
        }
    

    这似乎适合我。

    我认为您可以通过使用
    面板来获得所需的行为。PerformLayout
    而不是
    SuspendLayout
    /
    ResumeLayout

        void renderSubPanels()
        {
            //panel.SuspendLayout();
            bool verticalScrollVisible = listOfPanels.Count * 100 > panel.ClientSize.Height;
            foreach (Panel p in listOfPanels)
            {
                if (verticalScrollVisible)
                {
                    p.Width = panel.Width - System.Windows.Forms.SystemInformation.VerticalScrollBarWidth - 2;
                }
                else
                {
                    p.Width = panel.Width - 2;
                }
    
                p.Top = (listOfPanels.IndexOf(p) * 100) - Math.Abs(this.AutoScrollPosition.Y);
            }
            //panel.ResumeLayout();
            panel.PerformLayout();
        }
    


    这似乎对我有用。

    不幸的是,这似乎不起作用,我仍然可以看到水平滚动条。我会尝试使用FlowLayoutPanel作为最后的手段,但这将意味着重写大部分我宁愿避免的控件。以上只是该问题的一个非常基本的示例,它与实际情况相去甚远:-)@Equalsk我没有得到带有我推荐的更改的水平滚动条。记住关闭面板控件上的自动滚动。您也可以忽略那些
    面板。水平滚动
    属性。在进行更改之前,您是否确实获得了它?它在几个像素的公差范围内。我肯定已经对AutoScroll属性的所有实例进行了注释,就像您所说的,所以不是这样。我使用的是Windows 8,可能是特定于操作系统?@Equalsk我只处理您提供的代码。当AutoScroll关闭且AutoScrollMinSize.Width=0时,您将永远不会看到水平滚动条。我的代码就是这么做的。嗯,不知道还能告诉你什么。我也只是在用这个例子。不要担心top不起作用,它在真实版本中起作用,这只是本文中的一个演示。谢谢你的时间!不幸的是,这似乎不起作用,我仍然得到水平滚动条。我会尝试使用FlowLayoutPanel作为最后的手段,但这将意味着重写大部分我宁愿避免的控件。以上只是该问题的一个非常基本的示例,它与真实情况相差甚远:-)@Equalsk我没有得到带有我记录的更改的水平滚动条