我正在使用带有 C# 的 Visual Studio 2010。 Windows 窗体开发中是否存在以某种方式将标签与文本框链接的概念?有什么东西可以让他们作为一个整体一起移动吗?在 ASP.NET 世界中,标签控件有 AssociatedControlId 属性。我还想我记得 MS Access 表单设计器有某种方法将标签与控件关联(或链接)。 Visual Studio 世界中是否存在此功能?
如果没有,如何将标签与控件分组,以便在移动文本框时不必手动移动标签?
似乎没有内置的。不过,您可以开设自己的
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);
}
}
}
这是示例程序在我的系统上的样子:
不,没有——至少对于开箱即用的控件来说是这样。如果你想要这个,你可以通过用户控件来实现。
一般来说,winforms 的行驱动方式与 HTML 不同。
我的第二个@Neils 答案只是创建一个带有文本框的用户控件。该面板可用于对控件进行分组,但如果窗体上有很多控件,则可能会非常乏味。
如果您想要支持的不仅仅是文本框,WinForms 允许您创建自己的设计器。如果您从 ParentControlDesigner 类继承设计器,则可以将所需的任何控件放入自定义标签控件中。
如果您想将标签与其他控件(或一般的控件组)分组,请使用
System.Windows.Forms.Panel
控件。面板控件的具体用途是group collections of controls
。
如果您想要更高程度的控制(而不是使用面板),那么您可以创建一个
UserControl
,它封装了 Label
和 Control
。
您可以使用扩展方法来做到这一点,请按照示例:
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
这是我的解决方案,使用
TableLayoutPanel
放置标签和输入控件,
预设了一些有用的属性:
预览
代码可能需要进一步换行
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();
您可以使用制表符和助记符来实现此目的。例如:
假设我们有一个带有标签和文本框(以及其他控件)的表单。
标签上有 文本 =“&名称” 制表索引 = 5
文本框有 制表符索引 = 6
如果用户按 Alt-N,焦点将首先尝试转到标签(由于 助记符 &N )。 标签无法获得焦点,因此尝试将焦点集中在下一个控件上 成功的 Tab 键顺序(即文本框)。
顺便说一句,如果下一个控件是另一个无法获得焦点的控件,它会保留 遍历选项卡序列,直到找到可以获得焦点的选项卡序列。 它会这样做,直到再次碰到第一个控件,然后放弃。
我认为最好的选择是使用 GroupBox。
这个回答与 OA 的问题有点偏离,也许有点迟钝。但是,我多次想更改表单上数据输入项的可见性。正如之前的回复所示,带有标签组合的文本框在 WinForms 中不是标准的。要在一条指令中实现这两项更改的可见性,请将标签的父级设置为代码中的文本框,最有可能在表单的 OnLoad 中。
如果将标签和文本框创建为面板的实体,则标签必须将面板作为其父级才能更改整个组的可见性。那么该组合的所有其他好处都可用。