2010-06-21 24 views
0

我正在寻找在VS2008中使用VB.net或C#在Windows窗体应用程序中运行时动态安排标签位置(或任何控件)的最佳方式。在vb.net中动态安排控件的问题

我有一个显示用户创建的消息的控件。 这种控制有停靠在其保持针对每个消息中的报头信息的顶部的面板,称为pnlHeader

有8个标签:其中 4显示静态描述(例如“到”,“从”,“创建日期“,”完成日期“) 另外4个显示这些描述的相关数据。 (在运行时从MS SQL 2005 DB传入)。 静态标签被命名为:lblCreatedDateLbl和动态的:lblCreatedDate

应用程序运行于不同尺寸和分辨率的显示器,为此我想对所有的标签将自己与pnlHeader等间距根据当前宽度安排,的面板。起初,我只是在Designer中创建了标签,并使用了Anchors(一半标签设置为(Top,Left),另一半设置为(Top,Right))。该解决方案适用于大多数场景,但并不总是提供一致的解决方案,因此我决定将代码添加到代码中。

我认为通过为每个相应的对创建面板来处理标签会更容易。所以pnlCreatedDate将举行lblCreatedDateLbllblCreatedDate

我写了2种方法: 1定义每个标签,并将其添加到相关面板:Sub AddLabels ,另一个确定面板的宽度,并设置正确的位置:Sub SetLoc

目前,AddLabels在数据从数据库传入后调用InitializeComponent()SetLoc后在构造函数中运行。

我试过对宽度和大小参数进行微小的更改和调整,启用和禁用AutoSize,但没有返回一致的解决方案,而是要么所有的描述标签都放错了位置,要么完全不显示或完全不显示地点出现。如果我完全使用错误的方法,是否有人可以建议如何最好地处理此任务?

以下是我使用的方法。我非常感谢任何帮助如何最有效地执行此操作。我是一位newb编码员,但很想学习。所以任何帮助都会很棒,我为这样一个基本的问题和长时间的描述事先道歉。

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 

回答

1

在UI中使用TableLayoutPanel。

然后,您可以将TableLayoutPanel停靠到窗体的中心(从而填充窗口)。

一旦你有了TableLayoutPanel,你可以配置行/列为固定大小或总数的百分比。

然后,您将标签(和其他UI控件)放置到TabelLayoutPanel中的单元格中,并将适当的Anchors/Docks设置为控件在单元格中的位置。现在,当您调整窗口大小时,您的控件将根据您的TableLayoutPanel定义自动调整大小/移动。

+0

非常感谢你,这看起来好像是任务的逻辑控制。 一般来说,你会说尝试在代码中操纵UI的视觉方面是个坏主意吗? (而不是在可能的情况下在设计师处理它。) – ObjectiveCat 2010-06-21 17:16:15

+1

@AndalusianCat - 两者都不是完美的。设计师很好,但它可能会产生一些难看的代码。我的建议是使用Designer来关闭事情,然后转到代码中,并使用鼓励更好调整大小/流动的东西删除丑陋的硬编码值。 – 2010-06-21 17:18:58