5

我有一个包含 1 列和 3 行的 TableLayout 的表单,其中包含 2 个 FlowLayoutPanel 和一个文本框。所有行都是 AutoSize,列设置为 Percentage=100%。

每个 FlowLayoutPanel 包含多个 TextBox。FlowLayoutPanel 设置为: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 的高度设置不正确,它会在 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 Form 上,我得到了相同的行为。

我认为问题在于,当 FlowLayoutPanel 位于另一个也是 AutoSized 的容器中时,它无法传递给它的容器是首选大小。

可以做些什么来覆盖这个错误?

请帮助 谢谢, Yoram


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

4

3 回答 3

2

当您FlowLayoutPanel将. 我不确定,但这可能会使组合框在调整大小时成为“领先”控件。GroupBoxAutoSize=false


编辑(在您发表评论后)

“领先控制”是我试图表达的组框大小将决定 FLP 的大小,这不是一些官方术语。问题在于,对接和自动调整大小在本质上是相互竞争的,应该有人来控制。只有在减少停靠和自动调整大小并自己编程调整大小事件时才能做到这一点。

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

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();
}

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

于 2011-10-04T21:13:04.047 回答
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)

希望这可以帮助。

于 2012-06-13T05:57:18.417 回答
0

很抱歉迟到了,但我想建议你最好简单计算一下FlowLayoutPanels 及其父母的身高,而不是使用Gert Arnold 的答案,因为他的方式会导致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));
  }
}

笔记:

  • 当然,您必须用相应的名称替换YodaUserControl,parentOfFlpYoda和。flpYoda
  • OnAdded, OnRemoved&OnSizeChanged需要附加到flpYodas 对应的ControlAdded, ControlRemoved&SizeChanged事件上。

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

于 2019-10-08T09:31:28.450 回答