1 回答
TA贡献1786条经验 获得超11个赞
基于评论中描述的布局的解决方案和之前发布的此答案:
Center multiple rows of controls in a FlowLayoutPanel
描述:(
本文底部提供的测试表格的完整代码)
创建一个新表单(这里,命名为
frmTLPTest1
)添加两个面板。一个用于承载一些按钮,另一个将是 TableLayoutPanel 的容器。
将 Container 面板设置为
AutoScroll = true
,AutoSizeMode = AutoSizeMode.GrowAndShrink
, 设置所有 Anchors (Left, Top, Right, Bottom)在 Container 面板中,放置一个新的 TableLayoutPanel:将其设置为
AutoSize = true
,AutoSizeMode = AutoSizeMode.GrowAndShrink
,Dock = DockStyle.Top
从 TableLayoutPanel 中删除所有行和列,除了每个行和列(不能全部删除)。将两者的尺寸设置为
AutoSize
。
重要说明(也在链接答案中报告):
在 Form 构造函数中,删除了其中一个 RowStyles。这很重要:TLP 将保留 2 个 RowStyle。一个应用于现有的 Row;第二种样式将应用于您添加的第一行:仅应用于第一个,而不应用于其他。如果不删除此样式,则会影响布局。
用于向 TableLayoutPanel 添加行/从 TableLayoutPanel 中删除行的核心方法,使用 FlowLayoutPanel 作为 TLP Row 内容,最终也可以用作其他控件的容器。
TlpAddRow(TableLayoutPanel tlp, bool addRowCount)
方法:
将新的 FlowLayoutPanel 添加到指定的 TableLayoutPanel 的 Cell 中,并在请求时添加新的 Row。
由于设计器不允许删除所有行,因此第一行(FlowLayoutPanel) 不得增加行数:addRowCount
参数将设置为false
.
private Control TlpAddRow(TableLayoutPanel tlp, bool addRowCount)
{
var flp = new FlowLayoutPanel() {
Anchor = AnchorStyles.Top | AnchorStyles.Bottom,
AutoSize = true,
AutoSizeMode = AutoSizeMode.GrowAndShrink,
};
tlp.SuspendLayout();
if (addRowCount) tlp.RowCount += 1;
tlp.Controls.Add(flp, 0, tlp.RowCount - 1);
tlp.ResumeLayout(true);
return flp;
}
TLPRemoveRow(TableLayoutPanel tlp, Control control)方法(重载):
允许从指定的 TableLayoutPanel 中删除行。要删除的 Row 可以从用作 Row Container 的 Control 派生(此处为 FlowLayoutPanel,但它可以是 Panel、另一个 TableLayoutPanel 或其他一些类型的 Container 控件)。
也可以通过直接指定 Row 索引来移除 Row。
private void TLPRemoveRow(TableLayoutPanel tlp, Control control)
{
int ctlRow = tlp.GetRow(control);
TLPRemoveRow(tlp, ctlRow);
}
private void TLPRemoveRow(TableLayoutPanel tlp, int row)
{
if (row < tlp.RowCount - 1) {
for (int i = row; i < tlp.RowCount - 1; i++) {
tlp.SetRow(tlp.GetControlFromPosition(0, i + 1), i);
}
}
tlp.RowCount -= 1;
}
此布局的视觉结果:
https://i.stack.imgur.com/hJs0i.gif
由于通过测试而不是解释更容易理解它的工作原理,因此这是表单的完整布局:
测试表格( frmTLPTest1):
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
public partial class frmTLPTest1 : Form
{
public frmTLPTest1()
{
InitializeComponent();
tlp1.RowStyles.RemoveAt(1);
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
TlpAddRow(tlp1, false);
}
Random rnd = new Random();
Size[] sizes = new Size[] { new Size(75, 75), new Size(100, 100), new Size(125, 125)};
Color[] colors = new Color[] { Color.Red, Color.LightGreen, Color.YellowGreen, Color.SteelBlue };
Control selectedObject = null;
Control selectedParent = null;
private void btnAddControl_Click(object sender, EventArgs e)
{
Size size = new Size(125, 125);
if (chkRandom.Checked) size = sizes[rnd.Next(sizes.Length)];
var pBox = new PictureBox() {
Anchor = AnchorStyles.None,
BackColor = colors[rnd.Next(colors.Length)],
MinimumSize = size,
Size = size
};
bool drawborder = false;
pBox.MouseEnter += (s, evt) => { drawborder = true; pBox.Invalidate(); };
pBox.MouseLeave += (s, evt) => { drawborder = false; pBox.Invalidate(); };
pBox.MouseDown += (s, evt) => { selectedParent = pBox.Parent;
selectedObject = pBox; pBox.Invalidate();
};
pBox.Paint += (s, evt) => {
if (drawborder) {
ControlPaint.DrawBorder(evt.Graphics, pBox.ClientRectangle,
Color.White, ButtonBorderStyle.Solid);
}
};
if (tlp1.RowCount == 0) TlpAddRow(tlp1, true);
var ctl = tlp1.GetControlFromPosition(0, tlp1.RowCount - 1);
int overallWith = 0;
if (ctl.Controls?.Count > 0) {
overallWith = ctl.Controls.OfType<Control>().Sum(c => c.Width + c.Margin.Left + c.Margin.Right);
}
overallWith += ctl.Margin.Right + ctl.Margin.Left + pBox.Size.Width + pBox.Margin.Left + pBox.Margin.Right;
if (overallWith >= tlp1.Width) {
ctl = TlpAddRow(tlp1, true);
}
ctl.Controls.Add(pBox);
}
private void btnRemoveRow_Click(object sender, EventArgs e)
{
if (selectedParent is null) return;
if (selectedParent.Controls.Count > 0) {
for (int i = 0; i == selectedParent.Controls.Count - 1; i++) {
selectedParent.Controls[i].Dispose();
}
}
TLPRemoveRow(tlp1, selectedParent);
selectedParent.Dispose();
}
private void btnRemoveControl_Click(object sender, EventArgs e)
{
if (selectedObject is null) return;
Control parent = selectedObject.Parent;
selectedObject.Dispose();
if (parent?.Controls.Count == 0) {
TLPRemoveRow(tlp1, parent);
parent.Dispose();
}
}
private Control TlpAddRow(TableLayoutPanel tlp, bool addRowCount)
{
var flp = new FlowLayoutPanel() {
Anchor = AnchorStyles.Top | AnchorStyles.Bottom,
AutoSize = true,
AutoSizeMode = AutoSizeMode.GrowAndShrink,
};
tlp.SuspendLayout();
if (addRowCount) tlp.RowCount += 1;
tlp.Controls.Add(flp, 0, tlp.RowCount - 1);
tlp.ResumeLayout(true);
return flp;
}
private void TLPRemoveRow(TableLayoutPanel tlp, Control control)
{
int ctlRow = tlp.GetRow(control);
TLPRemoveRow(tlp, ctlRow);
}
private void TLPRemoveRow(TableLayoutPanel tlp, int row)
{
if (row < tlp.RowCount - 1) {
for (int i = row; i < tlp.RowCount - 1; i++) {
tlp.SetRow(tlp.GetControlFromPosition(0, i + 1), i);
}
}
tlp.RowCount -= 1;
}
}
测试表单设计器:
partial class frmTLPTest1
{
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
this.panToolbar = new System.Windows.Forms.Panel();
this.btnRemoveRow = new System.Windows.Forms.Button();
this.chkRandom = new System.Windows.Forms.CheckBox();
this.btnRemoveControl = new System.Windows.Forms.Button();
this.btnAddControl = new System.Windows.Forms.Button();
this.panBackground = new System.Windows.Forms.Panel();
this.tlp1 = new System.Windows.Forms.TableLayoutPanel();
this.panToolbar.SuspendLayout();
this.panBackground.SuspendLayout();
this.SuspendLayout();
//
// panToolbar
//
this.panToolbar.BackColor = System.Drawing.Color.DarkOliveGreen;
this.panToolbar.Controls.Add(this.btnRemoveRow);
this.panToolbar.Controls.Add(this.chkRandom);
this.panToolbar.Controls.Add(this.btnRemoveControl);
this.panToolbar.Controls.Add(this.btnAddControl);
this.panToolbar.Dock = System.Windows.Forms.DockStyle.Bottom;
this.panToolbar.Location = new System.Drawing.Point(0, 359);
this.panToolbar.Name = "panToolbar";
this.panToolbar.Size = new System.Drawing.Size(552, 55);
this.panToolbar.TabIndex = 2;
//
// btnRemoveRow
//
this.btnRemoveRow.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(32)))), ((int)(((byte)(32)))), ((int)(((byte)(32)))));
this.btnRemoveRow.FlatAppearance.MouseDownBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(64)))), ((int)(((byte)(0)))));
this.btnRemoveRow.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(64)))), ((int)(((byte)(0)))));
this.btnRemoveRow.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btnRemoveRow.ForeColor = System.Drawing.Color.White;
this.btnRemoveRow.Location = new System.Drawing.Point(261, 11);
this.btnRemoveRow.Name = "btnRemoveRow";
this.btnRemoveRow.Size = new System.Drawing.Size(119, 34);
this.btnRemoveRow.TabIndex = 4;
this.btnRemoveRow.Text = "Remove Row";
this.btnRemoveRow.UseVisualStyleBackColor = false;
this.btnRemoveRow.Click += new System.EventHandler(this.btnRemoveRow_Click);
//
// chkRandom
//
this.chkRandom.AutoSize = true;
this.chkRandom.ForeColor = System.Drawing.Color.White;
this.chkRandom.Location = new System.Drawing.Point(446, 20);
this.chkRandom.Name = "chkRandom";
this.chkRandom.Size = new System.Drawing.Size(94, 19);
this.chkRandom.TabIndex = 3;
this.chkRandom.Text = "Random Size";
this.chkRandom.UseVisualStyleBackColor = true;
//
// btnRemoveControl
//
this.btnRemoveControl.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(32)))), ((int)(((byte)(32)))), ((int)(((byte)(32)))));
this.btnRemoveControl.FlatAppearance.MouseDownBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(64)))), ((int)(((byte)(0)))));
this.btnRemoveControl.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(64)))), ((int)(((byte)(0)))));
this.btnRemoveControl.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btnRemoveControl.ForeColor = System.Drawing.Color.White;
this.btnRemoveControl.Location = new System.Drawing.Point(136, 11);
this.btnRemoveControl.Name = "btnRemoveControl";
this.btnRemoveControl.Size = new System.Drawing.Size(119, 34);
this.btnRemoveControl.TabIndex = 2;
this.btnRemoveControl.Text = "Remove Control";
this.btnRemoveControl.UseVisualStyleBackColor = false;
this.btnRemoveControl.Click += new System.EventHandler(this.btnRemoveControl_Click);
//
// btnAddControl
//
this.btnAddControl.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(32)))), ((int)(((byte)(32)))), ((int)(((byte)(32)))));
this.btnAddControl.FlatAppearance.MouseDownBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(64)))), ((int)(((byte)(0)))));
this.btnAddControl.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(64)))), ((int)(((byte)(0)))));
this.btnAddControl.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btnAddControl.ForeColor = System.Drawing.Color.White;
this.btnAddControl.Location = new System.Drawing.Point(11, 11);
this.btnAddControl.Name = "btnAddControl";
this.btnAddControl.Size = new System.Drawing.Size(119, 34);
this.btnAddControl.TabIndex = 0;
this.btnAddControl.Text = "Add Control";
this.btnAddControl.UseVisualStyleBackColor = false;
this.btnAddControl.Click += new System.EventHandler(this.btnAddControl_Click);
//
// panBackground
//
this.panBackground.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.panBackground.AutoScroll = true;
this.panBackground.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.panBackground.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(32)))), ((int)(((byte)(32)))), ((int)(((byte)(32)))));
this.panBackground.Controls.Add(this.tlp1);
this.panBackground.Location = new System.Drawing.Point(0, 0);
this.panBackground.Name = "panBackground";
this.panBackground.Size = new System.Drawing.Size(552, 360);
this.panBackground.TabIndex = 3;
//
// tlp1
//
this.tlp1.AutoSize = true;
this.tlp1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.tlp1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(32)))), ((int)(((byte)(32)))), ((int)(((byte)(32)))));
this.tlp1.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.Single;
this.tlp1.ColumnCount = 1;
this.tlp1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tlp1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tlp1.Dock = System.Windows.Forms.DockStyle.Top;
this.tlp1.Location = new System.Drawing.Point(0, 0);
this.tlp1.Name = "tlp1";
this.tlp1.RowCount = 1;
this.tlp1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlp1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 1F));
this.tlp1.Size = new System.Drawing.Size(552, 2);
this.tlp1.TabIndex = 4;
//
// frmTLPTest1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.ClientSize = new System.Drawing.Size(552, 414);
this.Controls.Add(this.panBackground);
this.Controls.Add(this.panToolbar);
this.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.Name = "frmTLPTest1";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "frmTLPTest1";
this.Load += new System.EventHandler(this.SOfrmTest1_Load);
this.panToolbar.ResumeLayout(false);
this.panToolbar.PerformLayout();
this.panBackground.ResumeLayout(false);
this.panBackground.PerformLayout();
this.ResumeLayout(false);
}
private System.Windows.Forms.Panel panToolbar;
private System.Windows.Forms.Button btnAddControl;
private System.Windows.Forms.Button btnRemoveControl;
private System.Windows.Forms.CheckBox chkRandom;
private System.Windows.Forms.Panel panBackground;
private System.Windows.Forms.TableLayoutPanel tlp1;
private System.Windows.Forms.Button btnRemoveRow;
}
- 1 回答
- 0 关注
- 98 浏览
添加回答
举报