title: Issues dynamically arranging controls in vb.net
body: <p>I am looking for the best way to dynamically arrange the location of labels (or any control for that matter) during runtime in a Windows Forms application using VB.net or C# in VS2008.</p>
  
  <p>I have a control that displays messages created by users.
  This control has a panel docked at the top which holds the header information for each message, called <code>pnlHeader</code></p>
  
  <p>There are 8 labels: 
  4 of them display static descriptions (e.g. "To", "From", "Created Date", "Completed Date")
  And the other 4 display the relevant data for those descriptions. (Passed in during runtime from a MS SQL 2005 DB).
  Static labels are named: <code>lblCreatedDateLbl</code> and dynamic ones: <code>lblCreatedDate</code></p>
  
  <p>The application runs on monitors of various size and resolution, therefor I would like for all of the labels to arrange themselves with equal spacing in <code>pnlHeader</code>, based on the current width of the panel.</p>
  
  <p>At first, I had simply created the labels in the Designer and used Anchors (half of the lables were set to (Top, Left) and the other half to (Top, Right)). This solution worked for most scenarios, but did not always provide a consistent solution, so I decided to add the controls in code instead. </p>
  
  <p>I thought it would be easier to work with the labels by creating a panel for each corresponding pair. So <code>pnlCreatedDate</code> would hold <code>lblCreatedDateLbl</code> and <code>lblCreatedDate</code></p>
  
  <p>I wrote 2 methods: 
  1 to define each label and add it to the relevant panel: <code>Sub AddLabels</code>
  and another to determine the width of the panels and set the correct location: <code>Sub SetLoc</code></p>
  
  <p>Currently, <code>AddLabels</code> runs in the constructor after <code>InitializeComponent()</code> and <code>SetLoc</code> is called after the data has been passed in from the database.</p>
  
  <p>I've tried making minor changes and tweaks to the width and size parameters, enabling and disabling AutoSize, but nothing returns a consistent solution, instead either all the description labels are misplaced, or do not appear at all or completely whack locations come up. If I'm using the wrong approach altogether, could someone please suggest how to best handle this task?</p>
  
  <p>Below are the methods I use. I would extremely appreciate any assistance on how to perform this most efficiently and effectively. I am a newb coder, but would love to learn. So any help would be great and I apologize in advance for such a basic question and long description.</p>
  
  <pre><code>   Private Sub AddLabels()
  
      'Label Created By:'
      lblCreatedByLbl.Location = New Point(0, 0)
      lblCreatedByLbl.AutoSize = True
      lblCreatedByLbl.Anchor = AnchorStyles.None
      lblCreatedByLbl.ForeColor = Color.FromKnownColor(KnownColor.ControlDark)
      lblCreatedByLbl.Font = New Font(New FontFamily("Microsoft Sans Serif"), 7, FontStyle.Bold, GraphicsUnit.Point)
      lblCreatedByLbl.Text = "By:"
  
      lblCreatedBy.Location = New Point((lblCreatedByLbl.Location.X + (lblCreatedByLbl.Width)), 0)
      lblCreatedBy.AutoSize = True
      lblCreatedBy.Anchor = AnchorStyles.None
      lblCreatedBy.Text = "Source"
      lblCreatedBy.ForeColor = Color.FromKnownColor(KnownColor.ControlDarkDark)
      lblCreatedBy.Font = New Font(New FontFamily("Microsoft Sans Serif"), 7, FontStyle.Bold, GraphicsUnit.Point)
  
      pnlCreatedBy.AutoSize = False
      pnlCreatedBy.Controls.Add(lblCreatedByLbl)
      pnlCreatedBy.Controls.Add(lblCreatedBy)
      pnlCreatedBy.Anchor = AnchorStyles.None
  
      'Label Target'
      lblTargetLbl.Location = New Point(0, 0)
     '... The same idea as above for each label'
  
  End Sub
  
  
  Private Sub SetLoc()
  
      pnlCreatedBy.Width = lblCreatedByLbl.Width + lblCreatedBy.Width
      pnlTarget.Width = lblTargetLbl.Width + lblTarget.Width
      pnlCreateDate.Width = lblCreateDateLbl.Width + lblCreateDate.Width
      pnlCompletedDate.Width = lblCompletedDateLbl.Width + lblCompletedDate.Width
  
      Dim loc As Integer = 0
      Dim x As Integer = (pnlHeader.Width - pnlCreatedBy.Width - pnlTarget.Width - pnlCreateDate.Width - pnlCompletedDate.Width) / 5
  
      loc += x
      pnlCreatedBy.Location = New Point(loc, 0)
      loc += pnlCreatedBy.Width + x
      pnlTarget.Location = New Point(loc, 0)
      loc += pnlTarget.Width + x
      pnlCreateDate.Location = New Point(loc, 0)
      loc += pnlCreateDate.Width + x
      pnlCompletedDate.Location = New Point(loc, 0)
      loc += pnlCompletedDate.Width + x
  
      pnlHeader.Controls.Add(pnlCreatedBy)
      pnlHeader.Controls.Add(pnlTarget)
      pnlHeader.Controls.Add(pnlCreateDate)
      pnlHeader.Controls.Add(pnlCompletedDate)
  
      pnlCreatedBy.BringToFront()
      pnlTarget.BringToFront()
      pnlCreateDate.BringToFront()
      pnlCompletedDate.BringToFront()
  
  End Sub
  </code></pre>