WinForms: Существует ли концепция ассоциирования метки с текстовым полем?

Я использую Visual Studio 2010 с С#. Существует ли концепция разработки Windows Forms как-то связать ярлык с текстовым полем? Что-то, чтобы они двигались вместе как единое целое? В мире ASP.NET существует свойство AssociatedControlId элемента управления меткой. Я также думаю, что я помню конструктора форм MS Access, который каким-то образом связывает (или связывает) метки с элементами управления. Эта функция существует даже в мире Visual Studio?

Если нет, как вы группируете метки с элементами управления, чтобы при перемещении текстового окна вам также не нужно вручную перемещать метку?

Ответы

Ответ 1

Нет, нет - по крайней мере, с элементами управления из коробки. Если вы хотите этого, вы можете достичь этого с помощью пользовательского элемента управления.

В общем случае winforms не управляется линией так же, как HTML.

Ответ 2

Кажется, что нет встроенного. Однако вы можете использовать свой собственный класс Field. Ниже приведен полный пример.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

namespace FieldClassTest
{
    class Field : FlowLayoutPanel
    {
        public Label label;
        public TextBox text_box;

        public Field(string label_text)
            : base()
        {
            AutoSize = true;

            label = new Label();
            label.Text = label_text;
            label.AutoSize = true;
            label.Anchor = AnchorStyles.Left;
            label.TextAlign = ContentAlignment.MiddleLeft;

            Controls.Add(label);

            text_box = new TextBox();

            Controls.Add(text_box);
        }
    }

    static class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            var form = new Form();

            var panel = new FlowLayoutPanel();
            panel.FlowDirection = FlowDirection.TopDown;
            panel.Dock = DockStyle.Fill;

            var first_name = new Field("First Name");
            panel.Controls.Add(first_name);

            var last_name = new Field("Last Name");
            panel.Controls.Add(last_name);

            form.Controls.Add(panel);

            Application.Run(form);
        }
    }
}

Здесь выглядит пример программы в моей системе:

enter image description here

Ответ 3

I Второй ответ @Neils просто создает пользовательский элемент управления с текстовым полем в нем. Панель может использоваться для группировки элементов управления, но это может быть довольно утомительно, если у вас много элементов управления в форме.

Если вы хотите поддерживать больше, чем просто текстовые поля, WinForms позволяет создать собственный дизайнер. Если вы наследуете своего дизайнера из класса ParentControlDesigner, вы можете удалить любой элемент управления, который вы хотите, в свой собственный элемент управления ярлыками.

Ответ 4

Если вы хотите группировать метки с другими элементами управления (или вообще групповыми элементами), используйте элемент управления System.Windows.Forms.Panel. Конкретная цель панели управления - group collections of controls.

Дополнительная информация Класс панели (System.Windows.Forms)

Если вам нужна более высокая степень контроля (вместо использования панели), вы можете создать UserControl, который инкапсулирует a Label и a Control.

Ответ 5

Я считаю, что лучше всего использовать GroupBox.

Ответ 6

Для этого вы можете использовать методы расширения, следуя примеру:

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

Ответ 7

Это мое решение, используя TableLayoutPanel для размещения метки и управления вводом,

Заданы некоторые полезные свойства:

  • Значок автоматического размера по контенту
  • Верхний край метки для вертикального выравнивания: средний стиль
  • Заполнить пространство с помощью управления вводом

Предварительный просмотр

preview

Коду может понадобиться дополнительная упаковка

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();