I have a WinForms application that has a TableLayoutPanel
; this is the definition code:
tableLayoutPanel1 = new TableLayoutPanel();
tableLayoutPanel1.Dock = DockStyle.Fill;
tableLayoutPanel1.AutoScroll = true;
tableLayoutPanel1.RowCount = users.Count + 1;
tableLayoutPanel1.ColumnCount = 1;
tableLayoutPanel1.GrowStyle = TableLayoutPanelGrowStyle.FixedSize;
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
foreach (String user in users)
{
tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 600F));
}
tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 600F));
int index = 0;
foreach (String user in users)
{
AddDockedControl(index, user);
index++;
}
AddDockedControl(index, null);
panel1.Controls.Add(tableLayoutPanel1);
private void AddDockedControl(int row, String userName)
{
AccountRowUC newUser = new AccountRowUC(this, userName, row);
newUser.BorderStyle = BorderStyle.FixedSingle;
newUser.Dock = DockStyle.Top;
tableLayoutPanel1.Controls.Add(newUser, 0, row);
}
Now, when I want to remove one of the rows, I'm using this code:
public void RemoveRowAtIndex(int index)
{
if (index >= tableLayoutPanel1.RowCount)
return;
// delete all controls of row that we want to delete
for (int i = 0; i < tableLayoutPanel1.ColumnCount; i++)
{
var control = tableLayoutPanel1.GetControlFromPosition(i, index);
tableLayoutPanel1.Controls.Remove(control);
}
// move up row controls that comes after row we want to remove
for (int i = index + 1; i < tableLayoutPanel1.RowCount; i++)
{
for (int j = 0; j < tableLayoutPanel1.ColumnCount; j++)
{
var control = tableLayoutPanel1.GetControlFromPosition(j, i);
if (control != null)
tableLayoutPanel1.SetRow(control, i - 1);
}
}
// remove last row
tableLayoutPanel1.RowStyles.RemoveAt(tableLayoutPanel1.RowCount - 1);
//tableLayoutPanel1.RowStyles.RemoveAt(index);
tableLayoutPanel1.RowCount--;
}
The problem is that when I remove a Row, a big space is left at the bottom of the table: the TableLayoutPanel won't reclaim the size of panel1
.
A solution base on the layout described in the comments and this answer, previously posted:
Center multiple rows of controls in a FlowLayoutPanel
Description:
(Full code of a test Form provided at bottom of this post)
frmTLPTest1
)AutoScroll = true
,AutoSizeMode = AutoSizeMode.GrowAndShrink
, set all the Anchors (Left, Top, Right, Bottom)AutoSize = true
,AutoSizeMode = AutoSizeMode.GrowAndShrink
,Dock = DockStyle.Top
AutoSize
.Important note (also reported in the linked answer):
The core methods used to Add Rows to/Remove Rows from the TableLayoutPanel, make use of a FlowLayoutPanel as the TLP Row content and can also be used as Container of other controls, eventually.
TlpAddRow(TableLayoutPanel tlp, bool addRowCount)
method:Adds a new FlowLayoutPanel to the Cell of the TableLayoutPanel specified and adds a new Row if requested.
Since the Designer won't allow to remove all the Rows, the First Row (FlowLayoutPanel) must not increment the Rows count: the
addRowCount
argument will be set tofalse
.TLPRemoveRow(TableLayoutPanel tlp, Control control)
method (overloaded):Allows to remove a Row from the specified TableLayoutPanel. The Row to be removed can be derived from the Control that is used as the Row Container (a FlowLayoutPanel, here, but it could be a Panel, another TableLayoutPanel, or some other type of Container control).
The Row can also be removed by directly specifying the Row index.
Visual results of this Layout:
Since it's easier to understand how it work by testing rather than explaining, here's the full layout of the Form:
Test Form (
frmTLPTest1
):Test Form Designer: