当内容不可见时防止自动调整大小的 TableLayoutPanel 行折叠

Prevent auto-sized TableLayoutPanel row from collapsing when content is invisible

我的问题很简单。我有一个 TableLayoutPanel,里面有很多行,每行都包含控件。

我希望 TableLayoutPanel 根据其内容自动调整自身大小,除非控件将其 Visible 属性 设置为 False

发生这种情况时,我想保留该行所在的空白 space。

目前,当控件的 Visible 属性 设置为 False 时,它所在的行会折叠。如果我检查调试器,我可以看到控件的 Height 仍然是 24,而不是 0

我一直在尝试不同的设置但都无济于事,谷歌搜索这个问题似乎只是发现人们在询问如何实现与我正在尝试做的完全相反的事情。

简单示例的完整代码如下:

Form1.vb

Option Strict On
Option Explicit On
Option Infer Off

Public Class Form1
    Private Sub Form1_Load( sender As Object,  e As EventArgs) Handles MyBase.Load
        For i As Integer = 0 To 2
            Dim c As New CheckBox()
            c.Text = "Checkbox" & i+1

            If i = 0
                AddHandler c.CheckedChanged,    Sub(sender2 As Object, e2 As EventArgs)
                                                    If TryCast(sender2, CheckBox).Checked
                                                        TryCast(TableLayoutPanel1.Controls(1), CheckBox).Visible = False
                                                    Else
                                                        TryCast(TableLayoutPanel1.Controls(1), CheckBox).Visible = True
                                                    End If
                                                End Sub
            End If

            TableLayoutPanel1.Controls.Add(c)
        Next
    End Sub
End Class

Form1.Designer.vb

<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form1
    Inherits System.Windows.Forms.Form

    'Form overrides dispose to clean up the component list.
    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
        Me.TableLayoutPanel1 = New System.Windows.Forms.TableLayoutPanel()
        Me.SuspendLayout
        '
        'TableLayoutPanel1
        '
        Me.TableLayoutPanel1.AutoSize = true
        Me.TableLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink
        Me.TableLayoutPanel1.ColumnCount = 1
        Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle())
        Me.TableLayoutPanel1.Location = New System.Drawing.Point(13, 13)
        Me.TableLayoutPanel1.Name = "TableLayoutPanel1"
        Me.TableLayoutPanel1.RowCount = 3
        Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle())
        Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle())
        Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle())
        Me.TableLayoutPanel1.Size = New System.Drawing.Size(0, 0)
        Me.TableLayoutPanel1.TabIndex = 0
        '
        'Form1
        '
        Me.AutoScaleDimensions = New System.Drawing.SizeF(6!, 13!)
        Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
        Me.ClientSize = New System.Drawing.Size(284, 261)
        Me.Controls.Add(Me.TableLayoutPanel1)
        Me.Name = "Form1"
        Me.Text = "Form1"
        Me.ResumeLayout(false)
        Me.PerformLayout

    End Sub
    Friend WithEvents TableLayoutPanel1 As System.Windows.Forms.TableLayoutPanel

End Class

我最初尝试@HansPassant 的评论无济于事。然而,在编写代码再次尝试时,我成功了,所以我不确定我最初做错了什么。

因此,此解决方案似乎可以解决问题,但如果有更好的方法来执行此操作,我将很高兴听到。

完整代码如下:

Form1.vb

Option Strict On
Option Explicit On
Option Infer Off

Public Class Form1
    Private Sub Form1_Load( sender As Object,  e As EventArgs) Handles MyBase.Load
        TableLayoutPanel1.SuspendLayout()
        TableLayoutPanel1.Visible = False

        TableLayoutPanel1.RowStyles.Clear()

        For i As Integer = 0 To 2
            TableLayoutPanel1.RowStyles.Add(New RowStyle(SizeType.AutoSize))


            Dim c As New CheckBox()
            c.Text = "Checkbox" & i+1

            If i = 0
                AddHandler c.CheckedChanged,    Sub(sender2 As Object, e2 As EventArgs)
                                                    If TryCast(sender2, CheckBox).Checked
                                                        TryCast(TableLayoutPanel1.Controls(1), CheckBox).Visible = False
                                                    Else
                                                        TryCast(TableLayoutPanel1.Controls(1), CheckBox).Visible = True
                                                    End If
                                                End Sub
            End If

            TableLayoutPanel1.Controls.Add(c, 0, i)
        Next

        TableLayoutPanel1.Visible = True

        TableLayoutPanel1.ResumeLayout()

        For i As Integer = 0 To TableLayoutPanel1.RowStyles.Count-1
            TableLayoutPanel1.RowStyles(i).SizeType = SizeType.Absolute
            TableLayoutPanel1.RowStyles(i).Height = TableLayoutPanel1.Controls(i).GetPreferredSize(New Size(0, 0)).Height + TableLayoutPanel1.Controls(i).Margin.Top + TableLayoutPanel1.Controls(i).Margin.Bottom
        Next
    End Sub
End Class

Form1.Designer.vb

<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form1
    Inherits System.Windows.Forms.Form

    'Form overrides dispose to clean up the component list.
    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
        Me.TableLayoutPanel1 = New System.Windows.Forms.TableLayoutPanel()
        Me.SuspendLayout
        '
        'TableLayoutPanel1
        '
        Me.TableLayoutPanel1.AutoSize = True
        Me.TableLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink
        Me.TableLayoutPanel1.ColumnCount = 1
        Me.TableLayoutPanel1.Location = New System.Drawing.Point(13, 13)
        Me.TableLayoutPanel1.Name = "TableLayoutPanel1"
        Me.TableLayoutPanel1.RowCount = 1
        Me.TableLayoutPanel1.Size = New System.Drawing.Size(0, 0)
        Me.TableLayoutPanel1.TabIndex = 0
        '
        'Form1
        '
        Me.AutoScaleDimensions = New System.Drawing.SizeF(6!, 13!)
        Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
        Me.ClientSize = New System.Drawing.Size(284, 261)
        Me.Controls.Add(Me.TableLayoutPanel1)
        Me.Name = "Form1"
        Me.Text = "Form1"
        Me.ResumeLayout(false)
        Me.PerformLayout

End Sub
    Friend WithEvents TableLayoutPanel1 As System.Windows.Forms.TableLayoutPanel

End Class