14

I have read a few articles on this but none seem to help. How do I align the label and textbox in the following case:

 Using frm As New frmWithTableLayout
     frm.TableLayoutPanel1.ColumnCount = 2
     frm.TableLayoutPanel1.RowCount = 3

     'create report Type'
     Dim lblReportType As New Label
     lblReportType.Text = "Report Type"
     lblReportType.Dock = DockStyle.Right
     Dim reportType As New System.Windows.Forms.TextBox()
     reportType.Text = "Income"
     frm.TableLayoutPanel1.Controls.Add(lblReportType, 0, 0)
     frm.TableLayoutPanel1.Controls.Add(reportType, 1, 0)
 End Using
Reddog
  • 15,219
  • 3
  • 51
  • 63
Denis
  • 11,796
  • 16
  • 88
  • 150
  • 3
    @Bradley There is no reason to remove the C# tag. This isn't a language-specific question and just because my example was in VB.NET doesn't make it a VB.NET question. I am open to all languages, just at the moment I was programming in VB.NET so the example was easier to put together in VB.NET. Someone who programs in C# might come up with a solution to the problem... – Denis Nov 03 '11 at 21:41
  • You forgot to add the ColumnStyles. Do this on a sample form first with the designer. Click the Show All Files icon in the Solution Explorer window. Open the node next to the form and double-click the Designer.vb file. Check out the code the designer generated. – Hans Passant Nov 03 '11 at 21:51
  • @Denis I would just make it a .net tag only then, since you left off F# and other .net based languages. – Bradley Uffner Nov 03 '11 at 22:18
  • `Label` should have `AutoSize` set to true – Konrad Morawski Jan 21 '14 at 15:36

6 Answers6

20

Labels and Textboxes are aligned within a TableLayoutPanel using the Anchor property. Usually, Anchor determines which edge of the parent a control will stick with when resizing. But with a TableLayoutPanel the Anchor property determines alignment within the cell. TextAlign has no effect on label alignment within a TLP.

From MSDN:

Change the value of the Button control's Anchor property to Left. The Button control moves to align with the left border of the cell.

Note: This behavior differs from the behavior of other container controls. In other container controls, the child control does not move when the Anchor property is set, and the distance between the anchored control and the parent container's boundary is fixed at the time the Anchor property is set.

https://msdn.microsoft.com/en-us/library/ms171691%28v=vs.90%29.aspx

Timbo
  • 345
  • 2
  • 7
8

You can align and stretch controls in a TableLayoutPanel with the Anchor and Dock properties.

lblReportType.TextAlign = ContentAlignment.MiddleCenter 
Damith
  • 62,401
  • 13
  • 102
  • 153
  • Tried TextAlign, no luck... have a hack in place that seems to be doing it pretty well but well, it's a total hack... – Denis Nov 03 '11 at 21:34
2

Replacing the above with:

  Using frm As New frmWithTableLayout
           frm.SetupTableLayout(2, 3) 

           'create report Type'
           Dim lblReportType As New Label
           lblReportType.Text = "Report Type"
           frm.LayoutControl(lblReportType, 0, 0)
           Dim tbReportType As New System.Windows.Forms.TextBox()
           tbReportType.Text = "Income"
           frm.LayoutControl(tbReportType, 1, 0)

           frm.ShowDialog()
   End Using

This is a total hack but this seems to work... Maybe someone will come up with something better:

 Public Sub LayoutControl(ByVal c As Control, ByVal column As Integer, ByVal row As Integer)
        If TypeOf c Is Label Then
            Dim clabel As Label = DirectCast(c, Label)
            clabel.TextAlign = ContentAlignment.TopCenter
            clabel.Dock = DockStyle.Right
            clabel.Margin = New Padding(clabel.Margin.Left, clabel.Margin.Top + 5, clabel.Margin.Right, clabel.Margin.Bottom)

        ElseIf TypeOf c Is System.Windows.Forms.TextBox Then
            Dim ctbox As System.Windows.Forms.TextBox = DirectCast(c, System.Windows.Forms.TextBox)
            ctbox.Margin = New Padding(0, 3, 0, 3)
            ctbox.TextAlign = HorizontalAlignment.Center
        End If

        TableLayoutPanel1.Controls.Add(c, column, row)
    End Sub

  Public Sub SetupTableLayout(ByVal numOfColumns As Integer, ByVal numOfRows As Integer)
        TableLayoutPanel1.ColumnCount = numOfColumns
        TableLayoutPanel1.RowCount = numOfRows
        While TableLayoutPanel1.RowStyles.Count < TableLayoutPanel1.RowCount
            TableLayoutPanel1.RowStyles.Add(New RowStyle())
        End While

        For Each row As RowStyle In TableLayoutPanel1.RowStyles
            With row
                .SizeType = SizeType.Percent
                .Height = 100 / TableLayoutPanel1.RowCount
            End With
        Next row
    End Sub
Denis
  • 11,796
  • 16
  • 88
  • 150
1

There are a few ways to approach it but doing it this way means you get the changes at design time (so no need to run the code to see how it will look), and it will retroactively correct all your existing layouts without needing to fix the TextAlignment and Anchor properties on each Label on a control-by-control basis.

1)

public class TableLayoutPanelEx : TableLayoutPanel
 {
    public TableLayoutPanelEx()
    {
        ControlAdded += OnControlAdded;            
    }

    private void OnControlAdded(object sender, ControlEventArgs args)
    {
        var control = args.Control as Label;
        if (control != null) { 
            control.TextAlign = ContentAlignment.MiddleLeft;                
            control.Anchor = (AnchorStyles.Bottom | AnchorStyles.Top | AnchorStyles.Left);
        }            
    }
}

2) Project-wide search/replace new TableLayoutPanel( with new TableLayoutPanelEx(.

3) ?

4) Profit

Before: enter image description here

After: enter image description here

nathanchere
  • 8,008
  • 15
  • 65
  • 86
1

The one that worked for me was this:

    Label lblAmountInWords = new Label();

    lblAmountInWords.Text = "FOUR THOUSAND THREE HUNDRED AND TWENTY ONLY";
    lblAmountInWords.Font = new Font("Arial", 9, FontStyle.Bold);
    lblAmountInWords.AutoSize = false;
    lblAmountInWords.Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top | AnchorStyles.Bottom;
    lblAmountInWords.TextAlign = ContentAlignment.MiddleCenter;

    tableLayoutPanelAmountInWords.Controls.Add(lblAmountInWords, 0, 0);
olleh
  • 1,915
  • 18
  • 21
0

If you want to align the Label and TextBox on the baseline, you can try to use the modified TextBox instead of the Label: https://stackoverflow.com/a/75815030/2408668

This solution works also for the higher DPIs.

sebetovsky
  • 101
  • 7