[使用AutoSize时的FlowLayoutPanel高度错误

问题描述 投票:5回答:3

我有一个表格,其中包含一个包含1列和3行的TableLayout,其中包含2个FlowLayoutPanels和一个文本框。所有行均为AutoSize,并且该列设置为Percentage = 100%。

每个FlowLayoutPanel包含多个TextBox。设置FlowLayoutPanels:LeftToRight,AutoSize = true,GrowAndShrink,Docking = Fill。

轮廓是:

Form
    TableLayout (Dock=Fill)
        FlowLayoutPanel(Dock=Fill, AutoSize=True, GrowShrink)
           More controls
        FlowLayoutPanel(Dock=Fill, AutoSize=True, GrowShrink)
           More controls
        TextBox(Dock=Fill, MultiLine=true)

[问题是,如果我将FlowLayoutPanel放置在也设置为AutoSize = true的GroupBox内,则FlowLayoutPanel Height的设置不正确,并且它在1行中显示了TextBoxes,将某些TextBoxes从表单中切出。

轮廓是:

Form
    TableLayout (Dock=Fill)
        GroupBox (Dock=Fill, AutoSize=True, GrowShrink) 
            FlowLayoutPanel(Dock=Fill, AutoSize=True, GrowShrink)
               More controls
        GroupBox (Dock=Fill, AutoSize=True, GrowShrink) 
            FlowLayoutPanel(Dock=Fill, AutoSize=True, GrowShrink)
               More controls
        TextBox(Dock=Fill, MultiLine=true)

顺便说一句,如果我使用而不是GroupBox,Panel甚至UserControl来保存FlowLayoutPanel,也会发生相同的事情。

BTW 2,即使没有TableLayout,也会发生这种情况。我尝试将GroupBox(带有FlowLayoutPanel)放置在AutoSized窗体上,并且得到相同的行为。

我认为问题是,当FlowLayoutPanel位于另一个也具有自动尺寸大小的容器中时,它无法传递给它的容器是首选大小。

如何解决此错误?

请帮助谢谢,Yoram


ps:我必须使用GroupBox在TextBoxes周围有一个漂亮的框架。

c# winforms groupbox flowlayoutpanel form-layout
3个回答
2
投票

也曾遇到此问题,并试图找出如何轻松解决此问题。尽管@GertArnold的回答确实有所帮助,但感觉有点麻烦,我在寻找其他解决方案。

[我发现流程面板的自动大小逻辑正在满足“最小”要求,并且通过添加最小高度的空白面板,我能够强制流程面板的宽度,从而使所有其他子控件可见。

所以在上面的示例中,最终布局将是:

Form
    TableLayout (Dock=Fill)
        GroupBox (Dock=Fill, AutoSize=True, GrowShrink) 
            FlowLayoutPanel(Dock=Fill, AutoSize=True, GrowShrink)
                Panel(Dock=Fill, Height = 1, MinimumSize = new System.Drawing.Size( Form.ClientSize.Width - TableLayout.Padding.Horizontal, 1))
                More controls
        GroupBox (Dock=Fill, AutoSize=True, GrowShrink) 
            FlowLayoutPanel(Dock=Fill, AutoSize=True, GrowShrink)
                Panel(Dock=Fill, Height = 1, MinimumSize = new System.Drawing.Size( Form.ClientSize.Width - TableLayout.Padding.Horizontal, 1))
                More controls
        TextBox(Dock=Fill, MultiLine=true)

希望这会有所帮助。


2
投票

[将FlowLayoutPanel停靠在GroupBox(或其他容器)中时,也可以保留其AutoSize=false。我不确定,但是在调整大小时,这可能会使groupbox成为“领先”控件。


编辑(在您的评论后)

“领导控制”是我试图表达组框大小将决定FLP大小的字眼,这不是官方术语。问题在于,对接和自动调整大小为fighting one another by nature,应该有人控制。仅当缩减停靠和自动调整大小并自己编程调整大小事件时,才能执行此操作。

[玩了一会儿之后,我终于想到了这个模型:

Form
    TableLayout (Dock=Fill)
        GroupBox () 
            FlowLayoutPanel(Dock=Fill)
               More controls

以及调整大小事件:

private void Form1_Resize(object sender, EventArgs e)
{
    this.SuspendLayout();
    this.groupBox.Width = this.Width - 20;
    this.groupBox.Height = 
        this.flowLayoutPanel.GetPreferredSize(this.groupBox.Size).Height + 20;
    this.ResumeLayout();
}

希望我能很好地理解你。至少这可以为您指明正确的方向。


0
投票

抱歉参加聚会太晚了,但我想建议您对FlowLayoutPanel及其父母身高的简单计算比使用Gert Arnold's answer做为更好,在删除子项GetPreferredSize()时返回等于“单行”的Height-即使仍然需要两行(至少在我的情况下)。

Control

注意:

  • 当然,您必须用相应的名称替换public YodaUserControl { InitializeComponent(); InitialHeight = parentOfFlp.Height; } private int InitialHeight { get; } private void OnAdded(object sender, ControlEventArgs args) => RefreshHeight(); private void OnRemoved(object sender, ControlEventArgs args) => RefreshHeight(); private void OnSizeChanged(object sender, EventArgs args) => RefreshHeight(); private void RefreshHeight() { if (flpYoda.Controls.Count > 1 && flpYoda.Controls[0] is Control control) { parentOfFlpYoda.Height = flpYoda.Height = InitialHeight * (int)Math.Ceiling( flpYoda.Controls.Count / Math.Floor( flpYoda.ClientSize.Width / (double)control.Width)); } } YodaUserControlparentOfFlpYoda
  • [flpYodaOnAddedOnRemoved必须附加到与OnSizeChangedflpYodaControlAdded事件相对应的ControlRemoved上。

如果需要进一步的帮助,请通过评论告知我。

© www.soinside.com 2019 - 2024. All rights reserved.