我有一个表格持有1列和3行,包含2个FlowLayoutPanels和一个文本框的TableLayout。所有行都是自动大小,列设置为Percentage=100%。
每个FlowLayoutPanel包含几个文本框。设置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内的GroupBox也设置为AutoSize=true, FlowLayoutPanel的高度没有正确设置,它显示的文本框在1行切割一些文本框的形式。
大纲是:
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)放在autosizing Form上,我得到了相同的行为。
我认为问题是,当FlowLayoutPanel是在另一个容器,也是自动调整大小它未能传递到它的容器是首选的大小。
可以做什么来覆盖这个bug??
请帮助谢谢,推断
p。s:我必须使用组框在文本框周围有一个漂亮的框架
也遇到过这个问题,并试图找出如何轻松解决这个问题。虽然@GertArnold的回答确实有帮助,但感觉有点麻烦,于是我寻找了另一个解决方案。
我发现Flow Panel的自动大小逻辑是在"最小"要求上工作的,通过添加一个最小高度的空白面板,我能够强制Flow Panel的宽度,从而使所有其他子控件可见。
所以在上面的例子中,最终的布局是:
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)
当您将FlowLayoutPanel
停靠在GroupBox
(或其他容器)中时,您不妨离开它们的AutoSize=false
。我不确定,但这可能会使分组框在大小方面成为"领先"控件。
编辑(在你的评论之后)
"领先控制"是我想表达的词,groupbox的大小将决定FLP的大小,这不是什么官方术语。问题是,对接和自动调整尺寸是相互冲突的,应该有人来控制。这只能在缩减对接和自动调整大小以及自己编程调整大小事件时完成。
在玩了一会儿之后,我终于想出了这个模型:
Form
TableLayout (Dock=Fill)
GroupBox ()
FlowLayoutPanel(Dock=Fill)
More controls
和resize事件:
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();
}
我希望我很好地理解了你。至少这会给你指明正确的方向。
抱歉迟到了,但我想建议你最好使用FlowLayoutPanel
s及其父级高度的简单计算,而不是使用Gert Arnold的答案,因为他的方法导致GetPreferredSize()
在删除子Control
时返回等于"单行"的Height
-即使仍然需要两行(至少在我的情况下)。
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
需要附在flpYoda
s对应的ControlAdded
,ControlRemoved
&SizeChanged
事件。
如果你需要进一步的帮助,请通过评论告诉我。