我创建了一个包含三个按钮的对话框。 我将这些按钮放在FlowLayoutPanel中,并将FlowDirection设置为TopDown。
我尝试将按钮调整到面板的宽度,然后将Anchor设置为Left + Top + Right。这似乎对FlowLayoutPanel无效。
有一个简单的解决方案吗?我知道我可以使用FlowLayoutPanel的OnResize事件,并朝着那个方向前进,但希望能够进行设计时设置。
答案 0 :(得分:22)
如果显式行管理不太烦人,您可以使用TableLayoutPanel
。
答案 1 :(得分:12)
要实现此布局,只需在FlowLayoutPanel
上设置以下所有属性:
AutoScroll = True
FlowDirection = TopDown
WrapContents = False
查看this了解详情
答案 2 :(得分:5)
FlowLayoutPanel可能是最合适的控件。它避免了TableLayoutPanel
的行管理方面。
答案 3 :(得分:0)
晚了将近十年,抱歉,但我想我会分享我刚刚编写的扩展程序,以在非流方向自动调整 FlowLayoutPanel 的子项的大小。例如,如果面板的 FlowDirection 是 TopDown,则不能将子项锚定到 Left 和 Right(它将子项缩小为零宽度),但是如果在 InitializeComponent()
之后在面板上调用此扩展,您将得到与您能够做到的效果相同。
它还可以指定一个孩子来填充流动方向上的剩余空间。
/// <summary>
/// Sets up children of a FlowLayoutPanel to auto-resize with the panel in the non-flow dimension.
/// (This is a workaround for the lack of support for anchoring both sides of a child inside FlowLayoutPanel.)
/// Optionally also resizes one control to fill remaining space in the flow dimension.
/// </summary>
/// <param name="fillControl">Optional child control to fill remaining space in the flow direction.</param>
public static void AutoSizeChildren(this FlowLayoutPanel panel, Control fillControl = null) {
// wrapping does not make sense with auto-resizing
panel.WrapContents = false;
var isVertical = panel.FlowDirection.In(FlowDirection.TopDown, FlowDirection.BottomUp);
int dim(Control c, bool flowDir = false) => isVertical ^ flowDir ? c.Width : c.Height;
void setDim(Control c, int size, bool flowDir = false) {
if (isVertical ^ flowDir)
c.Width = size;
else
c.Height = size;
}
var children = panel.Controls.Cast<Control>().ToList();
var relSizes = children.ToDictionary(c => c, c => dim(c) - dim(panel));
// update relative size when controls are resized
var isPanelResizing = false;
foreach (var child in children) {
child.Resize += (s, e) => {
if (!isPanelResizing)
relSizes[child] = dim(child) - dim(panel);
};
}
// resize children when panel is resized
panel.Resize += (s, e) => {
isPanelResizing = true;
foreach (var child in children)
setDim(child, dim(panel) + relSizes[child]);
isPanelResizing = false;
};
if (fillControl != null) {
// add the size difference between the panel and its children to the fillControl
void sizeFill() {
var childrenSize = children.Sum(c => dim(c, true) + (isVertical ? c.Margin.Vertical : c.Margin.Horizontal));
var diff = dim(panel, true) - childrenSize - (isVertical ? panel.Padding.Vertical : panel.Padding.Horizontal);
if (diff != 0)
setDim(fillControl, dim(fillControl, true) + diff, true);
}
panel.Resize += (s, e) => sizeFill();
foreach (var child in children)
child.Resize += (s, e) => sizeFill();
}
}