.net FlowLayoutPanel - 控件的自动宽度?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5395754/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
FlowLayoutPanel - Automatic Width for controls?
提问by MilMike
is it possible to make the inserted items in FlowLayoutPanel automatic size of the FlowLayoutPanel? Here is an example:
是否可以使 FlowLayoutPanel 中插入的项目自动调整 FlowLayoutPanel 的大小?下面是一个例子:
A form with 1 FlowLayoutPanel and 3 buttons inside:
一个包含 1 FlowLayoutPanel 和 3 个按钮的表单:


if I resize the form, the controls look like this: they arrange "left to right"
如果我调整表单的大小,控件看起来像这样:它们“从左到右”排列


What I want is this: The controls should have the width of the FlowLayoutPanel:
我想要的是:控件应该具有 FlowLayoutPanel 的宽度:


Any Ideas how to do this? I changed the FlowDirection and played with the Anchor property but with no luck.
任何想法如何做到这一点?我更改了 FlowDirection 并使用了 Anchor 属性,但没有运气。
I could of course Resize the controls in the FlowLayoutPanel_Resize event, but I want to add about 500 usercontrols - I tested it and it is slow.
我当然可以在 FlowLayoutPanel_Resize 事件中调整控件的大小,但是我想添加大约 500 个用户控件 - 我测试了它并且它很慢。
采纳答案by arbiter
I suggest you using TableLayoutPanel with one column in this case. I have found TableLayoutPanel much more predictable and solid than FlowLayoutPanel.
在这种情况下,我建议您将 TableLayoutPanel 与一列一起使用。我发现 TableLayoutPanel 比 FlowLayoutPanel 更可预测和更可靠。
Another option, if you still want to use FlowLayoutPanel, is to set first control width to desired one, and use Dock = Top for all other controls.
如果您仍想使用 FlowLayoutPanel,另一种选择是将第一个控件宽度设置为所需的宽度,并将 Dock = Top 用于所有其他控件。
回答by SuperLucky
It's simple way to do this. Just bind the SizeChanged evnent of you flowLayoutPannel and resize the containing control. Like:
这是执行此操作的简单方法。只需绑定您 flowLayoutPanel 的 SizeChanged 事件并调整包含控件的大小。喜欢:
private void myFlowLayoutPannel_SizeChanged(object sender, EventArgs e)
{
myFlowLayoutPannel.SuspendLayout();
foreach (Control ctrl in pnSMS.Controls)
{
if (ctrl is Button) ctrl.Width = pnSMS.ClientSize.Width;
}
myFlowLayoutPannel.ResumeLayout();
}
回答by Teolazza
here I have my StackPanel class:
这里我有我的 StackPanel 类:
/// <summary>
/// A stackpanel similar to the Wpf stackpanel.
/// </summary>
public class StackPanel: FlowLayoutPanel
{
public StackPanel(): base()
{
InitializeComponent();
this.ForceAutoresizeOfControls = true;
}
private void InitializeComponent()
{
this.SuspendLayout();
//
// StackPanel
//
this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.WrapContents = false;
this.ResumeLayout(false);
}
/// <summary>
/// Override it just in order to hide it in design mode.
/// </summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new bool WrapContents
{
get { return base.WrapContents; }
set { base.WrapContents = value; }
}
/// <summary>
/// Override it just in order to set its default value.
/// </summary>
[DefaultValue(typeof(AutoSizeMode), "GrowAndShrink")]
public override AutoSizeMode AutoSizeMode
{
get { return base.AutoSizeMode; }
set { base.AutoSizeMode = value; }
}
/// <summary>
/// Get or set a value that when is true forces the resizing of each control.
/// If this value is false then only control that have AutoSize == true will be resized to
/// fit the client size of this container.
/// </summary>
[DefaultValue(true)]
public bool ForceAutoresizeOfControls { get; set; }
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
this.SuspendLayout();
switch (FlowDirection)
{
case FlowDirection.BottomUp:
case FlowDirection.TopDown:
foreach (Control control in this.Controls)
if (ForceAutoresizeOfControls || control.AutoSize)
control.Width = this.ClientSize.Width - control.Margin.Left - control.Margin.Right;
break;
case FlowDirection.LeftToRight:
case FlowDirection.RightToLeft:
foreach (Control control in this.Controls)
if (ForceAutoresizeOfControls || control.AutoSize)
control.Height = this.ClientSize.Height - control.Margin.Top - control.Margin.Bottom;
break;
default:
break;
}
this.ResumeLayout();
}
protected override void OnLayout(LayoutEventArgs levent)
{
base.OnLayout(levent);
if (levent != null && levent.AffectedControl != null)
{
Control control = levent.AffectedControl;
if (ForceAutoresizeOfControls || control.AutoSize)
{
switch (FlowDirection)
{
case FlowDirection.BottomUp:
case FlowDirection.TopDown:
control.Width = this.ClientSize.Width - control.Margin.Left - control.Margin.Right;
break;
case FlowDirection.LeftToRight:
case FlowDirection.RightToLeft:
control.Height = this.ClientSize.Height - control.Margin.Top - control.Margin.Bottom;
break;
default:
break;
}
}
}
}
}
回答by CrazyTim
The FlowLayoutPanelarranges controls in a particular way, according to MSDN:
在FlowLayoutPanel以特定方式排列的控制,根据MSDN:
...for vertical flow directions, the FlowLayoutPanel control calculates the width of an implied column from the widest child control in the column. All other controls in this column with Anchoror Dockproperties are aligned or stretched to fit this implied column. The behavior works in a similar way for horizontal flow directions.
...对于垂直流向,FlowLayoutPanel 控件根据列中最宽的子控件计算隐含列的宽度。此列中具有Anchor或Dock属性的所有其他控件都对齐或拉伸以适合此隐含列。对于水平流动方向,该行为以类似的方式工作。
Its not ideal, but you can do this natively, as long as one child control is set to the same width as the container, and the rest of the controls are set to Dock.
它并不理想,但您可以在本机执行此操作,只要将一个子控件设置为与容器相同的宽度,其余控件设置为Dock.
回答by clakids
I Suggest... try playing with the anchors of the buttons... try setting it as
我建议......尝试使用按钮的锚点......尝试将其设置为
Button1.Anchor = (AnchoreStyle.Left or AnchoreStyle.Right)
or set it in the properties...
或在属性中设置它...
and then put it inside a Panel instead of the FlowLayoutPanel... ;)
然后把它放在一个面板而不是 FlowLayoutPanel 中......;)
回答by Gravitate
There is no need for a FlowLayoutPanelhere.
没有必要在FlowLayoutPanel这里。
You should be able to do what you want with a normal Panelcontrol.
Anchor it at all four sides so that it stretches with your form, then add your buttons and set them all to Dock: Top.
您应该能够使用正常Panel控件做您想做的事情。将它锚定在所有四个边上,使其与您的表单一起伸展,然后添加您的按钮并将它们全部设置为 Dock: Top。
Job Done.
任务完成。
回答by Martin Hasa
As other answers stated, the Panel itself is sufficient to handle your buttons. Bit of code that works for me:
正如其他答案所述,面板本身足以处理您的按钮。对我有用的代码:
public class ButtonWindow : Panel
{
public ButtonWindow()
{
Dock = DockStyle.Fill;
AutoScroll = true;
for (int i = 0; i < 500; i++)
{
Button button = new Button() { Height = 100, Dock = DockStyle.Top };
Controls.Add(button);
}
}
}
Have a nice day.
祝你今天过得愉快。

