问题描述
在 TableLayoutPanel 中,我有许多控件和一个用作视觉分隔符的标签。
最小工作示例:
表格只有一行,其内容设置为 Autosize
。
在设计模式下,如果我调整大按钮的高度 - 或删除它 - 表格会根据小按钮的高度调整大小。
红色分隔线(一个标签)对行高没有贡献,因为它是停靠的 (DockStyle.Left
)。
一切都很好。直到运行时。
如果在运行时大 Button 改变大小或被移除,TableLayoutPanel 保持相同大小,其高度仍设置为 Label 的高度(红色分隔线)! 尽管隔板被停靠,但桌子坚持要考虑到它的高度!
我该如何解决这个问题?
重现问题的说明:
-
下载示例项目 from my Dropbox。
-
点击大按钮,它会主动隐藏自己。
-
注意表格无缘无故地保持相同的大小!
解决方法
问题:
在 TableLayoutPanel 中,Label 用作两列之间的分隔符。
- 标签停靠在其单元格上。
- 唯一的 Row 的 RowStyle 设置为
SizeType.AutoSize
- Label 的 Cell 对应的 Column 的样式似乎设置为
SizeType.AutoSize
,其他 Columns 的样式似乎设置为SizeType.AutoSize
。
在设计类型中,当隐藏或删除另一个单元格中托管的控件时,TableLayoutPanel 会缩小到剩余控件的大小,而 Label 似乎也会相应地调整其高度。
或者,至少,这就是看起来会发生的事情。
部分取决于 .Net 版本,TableLayoutPanel 和 Label 可能会同意同时缩小。但这种行为可能不会重复多次。
当布局首次应用于所有受影响的控件时,表单设计器和运行时 LayoutEngine 的行为可能会有所不同。
如果在设计时再次显示控件然后将其删除,则 TableLayoutPanel 很可能会拒绝第二次缩小。
当项目运行,然后停止,然后返回到表单设计器时,可以观察到相同的行为。当其中一个控件被移除时,TableLayoutPanel 将不再缩小:现在应用默认布局,并且设计器的引擎将按照 designer.cs
文件中的描述运行。
如何解决:
如果实际上需要一个标签作为分隔符:
- 将标签固定到四面八方或停靠在
DockStyle.Fill
- 将标签
AutoSize
属性设置为true
(!Important) - 将 TableLayoutPanel
AutoSize
属性设置为true
- 将 TableLayoutPanel AutoSizeMode 属性设置为 GrowAndShrink (!Important)
- 将所有未用作分隔符的列的 ColumnStyle 设置为 SizeType.AutoSize
如果实际上不需要Label,我们可以绘制订阅CellPaint事件的TableLayoutPanel Cells的背景。
非常简单的操作,Label 可以被移除,所以它的 Layout 行为不再是一个问题。
用作分隔符的单元格的大小需要增加标签设置的左右Margin
的度量,以具有相同的空间.
其余的都一样。
这会用红色填充所有偶数列的单元格的背景。
当使用标准控件时,此颜色仅在运行时可见。可以在设计时使用在内部实现此行为的自定义控件使其可见。
private void someTableLayoutPanel_CellPaint(object sender,TableLayoutCellPaintEventArgs e)
{
if (e.Column % 2 != 0) {
e.Graphics.FillRectangle(Brushes.Red,e.CellBounds);
}
}
这是运行时(也包括设计时)的样子:
与 TableLayoutPanle 行为相关的其他信息:
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