Hi, 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.
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 pnlHeader
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: lblCreatedDateLbl
and dynamic ones: lblCreatedDate
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 pnlHeader
, based on the current width of the panel.
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.
I thought it would be easier to work with the labels by creating a panel for each corresponding pair. So pnlCreatedDate
would hold lblCreatedDateLbl
and lblCreatedDate
I wrote 2 methods:
1 to define each label and add it to the relevant panel: Sub AddLabels
and another to determine the width of the panels and set the correct location: Sub SetLoc
Currently, AddLabels
runs in the constructor after InitializeComponent()
and SetLoc
is called after the data has been passed in from the database.
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?
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.
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