如何将TableLayoutPanel中的所有列自动调整为完全相同的宽度?

时间:2009-05-05 09:11:39

标签: .net winforms tablelayoutpanel

我正在尝试创建一个相当广泛的UserControl,将方形控件合并到设计中,并允许调整大小。 因为设计需要正方形,所以我需要TableLayoutPanels中的所有列都具有相同的宽度,以便包含的停靠控件也是方形的。

不幸的是,TableLayoutPanel的行为并没有给我这个结果 使用TableLayoutPanel并将所有列设置为使用相同百分比的Control,(在一组7列中)给出6个宽度相等的列,以及第7个宽度可变的列。
我知道出现这种情况是因为每7个大小中有6个,在7列周围没有相同数量的列像素,第7列是这个不等式的溢出。

我想我想要的是类似于第8列的其他7列的溢出,允许所有7个“真实”列具有真正相等的宽度,但是对于第8列可以允许宽度为0 到目前为止,我找不到允许这种行为的设置。

有谁能告诉我如何让TableLayoutPanel做我想做的事情,或者我将不得不开始编写大量的解决方法代码?

编辑:

为了回应Yacoder的回答,我添加了一些代码来演示这个问题,另一个代码显示了使用TableLayoutPanel和Dock属性的标准功能来解决它​​的不成功,天真的尝试

问题演示:

Public Class Form1
Inherits System.Windows.Forms.Form
Public Sub New()
    Me.InitializeComponent()
End Sub
'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.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
    Me.TableLayoutPanel1.ColumnCount = 7
    Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 14.28571!))
    Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 14.28572!))
    Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 14.28572!))
    Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 14.28572!))
    Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 14.28572!))
    Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 14.28572!))
    Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 14.28572!))
    Me.TableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill
    Me.TableLayoutPanel1.Location = New System.Drawing.Point(0, 0)
    Me.TableLayoutPanel1.Name = "TableLayoutPanel1"
    Me.TableLayoutPanel1.RowCount = 7
    Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.28571!))
    Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.28571!))
    Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.28571!))
    Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.28571!))
    Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.28571!))
    Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.28571!))
    Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.28571!))
    Me.TableLayoutPanel1.Size = New System.Drawing.Size(261, 264)
    Me.TableLayoutPanel1.TabIndex = 0
    '
    'Form1
    '
    Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
    Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
    Me.ClientSize = New System.Drawing.Size(261, 264)
    Me.Controls.Add(Me.TableLayoutPanel1)
    Me.Name = "Form1"
    Me.Text = "Form1"
    Me.ResumeLayout(False)

End Sub
Friend WithEvents TableLayoutPanel1 As System.Windows.Forms.TableLayoutPanel
Private labelList As List(Of Label)
Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
    MyBase.OnLoad(e)
    labelList = New List(Of Label)
    For JJ As Integer = 0 To Me.TableLayoutPanel1.ColumnCount - 1
        For II As Integer = 0 To Me.TableLayoutPanel1.RowCount - 1
            Dim addLabel As New Label
            Me.TableLayoutPanel1.Controls.Add(addLabel, JJ, II)
            addLabel.Dock = DockStyle.Fill
            Me.labelList.Add(addLabel)
        Next
    Next
End Sub
Private Sub TableLayoutPanel1_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles TableLayoutPanel1.Resize
    If Me.labelList IsNot Nothing Then
        For Each labelIn As Label In Me.labelList
            labelIn.Text = labelIn.Width.ToString & ", " & labelIn.Height.ToString
        Next
    End If
End Sub
End Class

天真的解决方案:

Public Class Form1
Inherits System.Windows.Forms.Form
Public Sub New()
    Me.InitializeComponent()
End Sub
'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.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
    Me.TableLayoutPanel1.ColumnCount = 8
    Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 14.28571!))
    Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 14.28572!))
    Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 14.28572!))
    Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 14.28572!))
    Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 14.28572!))
    Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 14.28572!))
    Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 14.28572!))
    Me.TableLayoutPanel1.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 0.0!))
    Me.TableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill
    Me.TableLayoutPanel1.Location = New System.Drawing.Point(0, 0)
    Me.TableLayoutPanel1.Name = "TableLayoutPanel1"
    Me.TableLayoutPanel1.RowCount = 8
    Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.28571!))
    Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.28571!))
    Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.28571!))
    Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.28571!))
    Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.28571!))
    Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.28571!))
    Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 14.28571!))
    Me.TableLayoutPanel1.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 0.0!))
    Me.TableLayoutPanel1.Size = New System.Drawing.Size(261, 264)
    Me.TableLayoutPanel1.TabIndex = 0
    '
    'Form1
    '
    Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
    Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
    Me.ClientSize = New System.Drawing.Size(261, 264)
    Me.Controls.Add(Me.TableLayoutPanel1)
    Me.Name = "Form1"
    Me.Text = "Form1"
    Me.ResumeLayout(False)

End Sub
Friend WithEvents TableLayoutPanel1 As System.Windows.Forms.TableLayoutPanel
Private labelList As List(Of Label)
Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
    MyBase.OnLoad(e)
    labelList = New List(Of Label)
    For JJ As Integer = 0 To Me.TableLayoutPanel1.ColumnCount - 1
        For II As Integer = 0 To Me.TableLayoutPanel1.RowCount - 1
            Dim addLabel As New Label
            Me.TableLayoutPanel1.Controls.Add(addLabel, JJ, II)
            addLabel.Dock = DockStyle.Fill
            Me.labelList.Add(addLabel)
        Next
    Next
End Sub
Private Sub TableLayoutPanel1_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles TableLayoutPanel1.Resize
    If Me.labelList IsNot Nothing Then
        For Each labelIn As Label In Me.labelList
            labelIn.Text = labelIn.Width.ToString & ", " & labelIn.Height.ToString
        Next
    End If
End Sub
End Class

对于重新绘制此代码的糟糕表现,我深表歉意。

3 个答案:

答案 0 :(得分:10)

也许我不太明白这个问题,但是......那就是我所做的:

  1. 创建新表单
  2. 在表单上删除TableLayoutPanel,并设置Dock = Fill
  3. 在表单设计窗口中(如果您使用的是VS),单击TableLayoutPanel上的小箭头打开包含任务的菜单,然后转到“编辑行和列...”
  4. 在该窗口中添加所需数量的列,并将所有列设置为整个大小的“百分比”,并将相同的数字放在任何位置。您可以输入任何数字,只要确保它是相同的,VS将自动使总和等于100%。
  5. 而且......它应该可以工作,至少当我调整这样的形式时,我看到所有列都重新调整大小......

    如果您不在VS中,或者遇到该方法的麻烦,这是我在Designer类中自动生成的代码:

        this.tableLayoutPanel1.ColumnCount = 7;
        this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 14.28571F));
        this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 14.28571F));
        this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 14.28571F));
        this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 14.28571F));
        this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 14.28571F));
        this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 14.28571F));
        this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 14.28571F));
    

答案 1 :(得分:1)

我试图在我的环境中设置它以及阅读你的帖子大约6或7次,我无法确定你正在尝试做什么。我有6列已停靠的SWF GroupBox对象,以填充设置为相同%宽度的列,因此我可以很容易地看到它们调整大小。我还有第7列设置为0px绝对宽度,以作为溢出。这可以像我期望的那样工作。

我无法确定这个设置有什么问题和/或你想要它做什么。你能否更好地描述一下TableLayoutPanel需要做什么?

答案 2 :(得分:0)

public MainForm()
{
    TableLayoutPanel pnlDragAndDrop = new TableLayoutPanel();

    // make the panel full width
    pnlDragAndDrop.Dock = DockStyle.Fill;

    // be sure to add columns and rows explicitly!
    pnlDragAndDrop.ColumnCount = 2;
    pnlDragAndDrop.RowCount = 1;

    // add a border just for testing
    pnlDragAndDrop.CellBorderStyle = 
        TableLayoutPanelCellBorderStyle.InsetDouble;
    pnlDragAndDrop.CellPaint += 
        new TableLayoutCellPaintEventHandler(TblLayoutPanel_CellPaint);

    // add a column style for each column!
    for (int i = 0; i < pnlDragAndDrop.ColumnCount * pnlDragAndDrop.RowCount; ++i)
    {
        pnlDragAndDrop.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
    }

    // add the panel to the form
    this.Controls.Add(pnlDragAndDrop);
}

private void TblLayoutPanel_CellPaint(object sender, TableLayoutCellPaintEventArgs e)
{
    // Add a border around each cell
    e.Graphics.DrawLine(
        Pens.Black, 
        e.CellBounds.Location, 
        new Point(e.CellBounds.Right, e.CellBounds.Top)
        );
}