WinForms:是否有将标签与文本框关联的概念?

问题描述 投票:0回答:9

我正在使用带有 C# 的 Visual Studio 2010。 Windows 窗体开发中是否存在以某种方式将标签与文本框链接的概念?有什么东西可以让他们作为一个整体一起移动吗?在 ASP.NET 世界中,标签控件有 AssociatedControlId 属性。我还想我记得 MS Access 表单设计器有某种方法将标签与控件关联(或链接)。 Visual Studio 世界中是否存在此功能?

如果没有,如何将标签与控件分组,以便在移动文本框时不必手动移动标签?

c# visual-studio winforms textbox label
9个回答
24
投票

似乎没有内置的。不过,您可以开设自己的

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


11
投票

不,没有——至少对于开箱即用的控件来说是这样。如果你想要这个,你可以通过用户控件来实现。

一般来说,winforms 的行驱动方式与 HTML 不同。


2
投票

我的第二个@Neils 答案只是创建一个带有文本框的用户控件。该面板可用于对控件进行分组,但如果窗体上有很多控件,则可能会非常乏味。

如果您想要支持的不仅仅是文本框,WinForms 允许您创建自己的设计器。如果您从 ParentControlDesigner 类继承设计器,则可以将所需的任何控件放入自定义标签控件中。


1
投票

如果您想将标签与其他控件(或一般的控件组)分组,请使用

System.Windows.Forms.Panel
控件。面板控件的具体用途是
group collections of controls


更多信息 面板类(System.Windows.Forms)

如果您想要更高程度的控制(而不是使用面板),那么您可以创建一个

UserControl
,它封装了
Label
Control


1
投票

您可以使用扩展方法来做到这一点,请按照示例:

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

1
投票

这是我的解决方案,使用

TableLayoutPanel
放置标签和输入控件,

预设了一些有用的属性:

  • 按内容自动调整标签大小
  • 标签边距顶部为vertical-align:middle样式
  • 通过输入控件填充剩余空间

预览

代码可能需要进一步换行

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

用途:

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

1
投票

您可以使用制表符和助记符来实现此目的。例如:

假设我们有一个带有标签和文本框(以及其他控件)的表单。

标签上有 文本 =“&名称” 制表索引 = 5

文本框有 制表符索引 = 6

如果用户按 Alt-N,焦点将首先尝试转到标签(由于 助记符 &N )。 标签无法获得焦点,因此尝试将焦点集中在下一个控件上 成功的 Tab 键顺序(即文本框)。

顺便说一句,如果下一个控件是另一个无法获得焦点的控件,它会保留 遍历选项卡序列,直到找到可以获得焦点的选项卡序列。 它会这样做,直到再次碰到第一个控件,然后放弃。


0
投票

我认为最好的选择是使用 GroupBox。


0
投票

这个回答与 OA 的问题有点偏离,也许有点迟钝。但是,我多次想更改表单上数据输入项的可见性。正如之前的回复所示,带有标签组合的文本框在 WinForms 中不是标准的。要在一条指令中实现这两项更改的可见性,请将标签的父级设置为代码中的文本框,最有可能在表单的 OnLoad 中。

如果将标签和文本框创建为面板的实体,则标签必须将面板作为其父级才能更改整个组的可见性。那么该组合的所有其他好处都可用。

© www.soinside.com 2019 - 2024. All rights reserved.