Inside a TableLayoutPanel I have are a number of controls and a Label I am using as a visual divider.
Minimal working example:
The table has a single row and it's set to Autosize
to its contents.
In Design Mode, if I adjust the height of the large Button - or delete it - the table resizes based on the height of the small Button.
The red divider (a Label) doesn't contribute to the row height because it is docked (DockStyle.Left
).
All well and good. Until run-time.
If, at run-time, the large Button changes size or is removed, the TableLayoutPanel remains the same size, its height still set to the height of the Label (the red divider)!
Despite the divider being docked, the table insists on taking its height into account!
How can I fix this?
Instructions to reproduce the problem:
Download the example project from my Dropbox.
Run the project (either from source or using the provided executable).
Click the Large Button, which will obligingly hide itself.
Notice that the table remains the same size for no good reason!
Problem:
In a TableLayoutPanel, a Label is used as separator between two Columns.
SizeType.AutoSize
SizeType.AutoSize
, the other Columns' style seems to be SizeType.AutoSize
.At design-type, when a Control hosted in another Cell is hidden or removed, the TableLayoutPanel shrinks to the size of the remaining Control and the Label appear to also resize its height accordingly.
Or, at least, this is what it appears to happen.
Partially depending on the .Net version, the TableLayoutPanel and the Label may agree to shrink at the same time. But this behavior may not repeat more than once.
The Form designer and the run-time LayoutEngine can behave differently when the Layout is first applied to all Controls affected.
If a Control is shown again and then removed, at design-time, the TableLayoutPanel will most probably refuse to shrink a second time.
The same behavior can be observed when the Project is run, then stopped, then back to the Form Designer. When one of the Controls is removed, the TableLayoutPanel won't shrink anymore: the default Layout is now applied and the Designer's engine will behave as described in the designer.cs
file.
How to solve:
If a Label is actually required as separator:
DockStyle.Fill
AutoSize
property to true
(!Important)AutoSize
property to true
In case the Label is not actually needed, we can draw the background of TableLayoutPanel Cells subscribing to the CellPaint event.
It's a quite simple operation, the Label can be removed, so its Layout behavior is not a concern anymore.
The size of the Cell used as separator needs to be increased by the measure of the left and right Margin
the Label was set to, to have the same space.
All the rest remains the same.
This fills the background of Cells of all even Columns with a red color.
This color is only visible at run-time when using a standard Control. It can be made visible at design-time with a Custom Control that implements this behavior internally.
private void someTableLayoutPanel_CellPaint(object sender, TableLayoutCellPaintEventArgs e)
{
if (e.Column % 2 != 0) {
e.Graphics.FillRectangle(Brushes.Red, e.CellBounds);
}
}
This is how it looks like at run-time (but also at design-time):
Other information related to the TableLayoutPanle behavior:
Remove Row inside TableLayoutPanel makes a layout problem
How to adjust TableLayoutPanel to wrap content by height and weight? (dynamically)
Dynamically added rows to a TableLayoutPanel are displayed on a different row position
Adjust free space in a TableLayoutPanel
Center multiple rows of controls in a FlowLayoutPanel