WinForms: Is there a concept of associating a labe

2019-01-27 12:30发布

I'm using Visual Studio 2010 with C#. Is there a concept in Windows Forms development of somehow linking a label with is text box? Something so that they move together as a unit? In the ASP.NET world, there is the AssociatedControlId property of the label control. I also think I remember MS Access form designer having some way of associating (or linking) labels with controls. Does this feature even exist in Visual Studio world?

If not, how do you group labels with controls such that if you move a text box you don't have to manually move the label also?

7条回答
Animai°情兽
2楼-- · 2019-01-27 13:15

i think the best bet would be to use a GroupBox.

查看更多
男人必须洒脱
3楼-- · 2019-01-27 13:19

You can use extension methods to do it, follow example:

Private associatedLabels As New Dictionary(Of Control, Label)    
<Extension()>
Public Sub AssociateLabel(ByVal control As Control, ByVal label As Label)
    If (Not associatedLabels.ContainsKey(control)) Then
        associatedLabels.Add(control, label)
    End If
End Sub

<Extension()>
Public Function GetAssociatedLabel(ByVal control As Control) As Label
    If (associatedLabels.ContainsKey(control)) Then
        Return associatedLabels(control)
    Else
        Throw New Exception("There is no associated label")
    End If
End Function
查看更多
虎瘦雄心在
4楼-- · 2019-01-27 13:24

No there is not - at least with the out of the box controls. If you want this you could achieve it with a user control.

In general the winforms is not line driven in the same way as HTML is.

查看更多
冷血范
5楼-- · 2019-01-27 13:26

I 2nd @Neils answer of just creating a user control with a textbox in it. The panel can be used to group controls, but it can be pretty tedious if you have a lot of controls on the form.

If you want to support more than just textboxes, WinForms allows you to create your own designer. If you inherit your designer from the ParentControlDesigner class, you can drop any control you want into your custom label control.

查看更多
该账号已被封号
6楼-- · 2019-01-27 13:31

This is my solution, using a TableLayoutPanel to place label and input control,

Presetted some useful properties:

  • Auto size label by content
  • Label margin top for vertical-align:middle like style
  • Fill remain space by input control

Preview

preview

The code may need further wrap

internal class TextBoxField : TableLayoutPanel
{
    private readonly TextBox _textBox;

    public string Text
    {
        get => _textBox.Text;
        set => _textBox.Text = value;
    }

    public TextBoxField(string labelText)
    {
        var label = new Label { Text = labelText, AutoSize = true };
        var labelMargin = label.Margin;
        labelMargin.Top = 8;
        label.Margin = labelMargin;
        _textBox = new TextBox { Dock = DockStyle.Fill };

        AutoSize = true;

        ColumnCount = 2;
        RowCount = 1;
        ColumnStyles.Add(new ColumnStyle());
        ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
        RowStyles.Add(new RowStyle());
        Controls.Add(label, 0, 0);
        Controls.Add(_textBox, 1, 0);
    }
}

internal class DateTimePickerField : TableLayoutPanel
{
    private readonly DateTimePicker _dateTimePicker;

    public DateTime Value
    {
        get => _dateTimePicker.Value;
        set => _dateTimePicker.Value = value;
    }

    public DateTimePickerField(string labelText)
    {
        var label = new Label { Text = labelText, AutoSize = true };
        var labelMargin = label.Margin;
        labelMargin.Top = 8;
        label.Margin = labelMargin;
        _dateTimePicker = new DateTimePicker { Dock = DockStyle.Fill };

        AutoSize = true;

        ColumnCount = 2;
        RowCount = 1;
        ColumnStyles.Add(new ColumnStyle());
        ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
        RowStyles.Add(new RowStyle());
        Controls.Add(label, 0, 0);
        Controls.Add(_dateTimePicker, 1, 0);
    }
}

Useage:

var frm = new Form
{
    AutoSize = true,
    StartPosition = FormStartPosition.CenterParent,
    Text = "Assoc Device",
};

var txtGpsCode = new TextBoxField("GpsCode") { Dock = DockStyle.Bottom, TabIndex = 1 };
var dtp = new DateTimePickerField("Expire date") { Dock = DockStyle.Bottom, TabIndex = 2 };
var button = new Button { Text = "OK", DialogResult = DialogResult.OK, Dock = DockStyle.Bottom };

frm.Controls.Add(txtGpsCode);
frm.Controls.Add(dtp);
frm.Controls.Add(button);

frm.AcceptButton = button;

frm.Height = 0;

frm.ShowDialog();
查看更多
男人必须洒脱
7楼-- · 2019-01-27 13:33

If you want to group labels with other controls (or group controls in general), then use the System.Windows.Forms.Panel control. The specific purpose of the Panel control is to group collections of controls.

More information Panel Class (System.Windows.Forms)

If you want a higher degree of control (rather than using a Panel), then you could create a UserControl, that encapsulates a Label and a Control.

查看更多
登录 后发表回答