说,如果我正在使用一个Label,我想在一个窗体上的多个(如三个)位置使用。我可以使用三个不同的标签,但如果我只能使用一个标签的副本,它会简单得多。后一种方法将允许我在一个地方更改与标签相关的属性,而使用前一种方法时,我必须去三个标签中的每一个来更改它们的属性。希望我的问题很明确。我可以使用Windows窗体控件的多个副本吗?
有没有办法使用同一个Windows窗体控件的多个副本?
说,如果我正在使用一个Label,我想在一个窗体上的多个(如三个)位置使用。我可以使用三个不同的标签,但如果我只能使用一个标签的副本,它会简单得多。后一种方法将允许我在一个地方更改与标签相关的属性,而使用前一种方法时,我必须去三个标签中的每一个来更改它们的属性。希望我的问题很明确。我可以使用Windows窗体控件的多个副本吗?
有没有办法使用同一个Windows窗体控件的多个副本?
例如,您想让设计器中的标签文字相同。
我们做一个类,说LabelTextResourced
public class LabelTextResourced: Label
{
private string _textResourceName;
public string TextResourceName
{
get { return _textResourceName; }
set
{
_textResourceName = value;
if (!string.IsNullOrEmpty(_textResourceName))
base.Text = Properties.Resources.ResourceManager.GetString(_textResourceName);
}
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public override string Text
{
get { return base.Text; }
set
{
// Set is done by resource name.
}
}
}
生成项目,现在你可以添加LabelTextResourced
控制你的设计师。
右键单击您的项目并转至属性并选择资源选项卡。 添加资源,例如:{Name: "LabelText", Value: "Hiiiiii!!!"}
现在,返回到窗体设计器,选择LabelTextResourced
您的实例,并设置它的TextResourceName
属性LabelText
。
重新构建,现在您应该看到您的标签文本是从资源中设置的。现在你可以有很多标签,他们的文本都是从一个位置设置的,并且将LabelText
资源(和构建)结果改为所有人的LabelTextResourced
控件,其LabelText
为TextResourceName
。
这只是一个起点,您可以通过一些努力来自定义此类和任何其他属性。
+1作为创意答案。我有一个问题:你将如何在运行时更新这个...? – 2014-11-06 18:47:55
这是一个全新的问题,您可以在运行时编辑资源文件,但这些更改不会反映在您的控件中,我认为提供一种从资源文件中再次获取值的方法将解决问题@ Ric.Net – dotctor 2014-11-06 18:53:33
您可以将其中一个控件实例设置为“模板”并将所有必要的属性复制到其他实例(当然,只留下那些位置)。
正如@nim建议,你可以创建一个属性映射器。当然,在设计时,事情可能看起来很丑。例如:
public partial class MyForm : Form
{
public MyForm()
{
InitializeComponent();
PropertyMapper.Map(txtBox1, textBox2,
new[] { "width", "font", "forecolor", "backcolor", "text" });
}
}
public static class PropertyMapper
{
public static void Map(Control source, Control target, params string[] properties)
{
properties = properties.Select(p => p.ToLowerInvariant()).ToArray();
foreach (var prop in source.GetType().GetProperties()
.Where(p => properties.Contains(p.Name.ToLowerInvariant()))
.Where(prop => prop.CanWrite))
{
prop.SetValue(target, prop.GetValue(source));
}
}
}
以及什么是解决方案设计时间? – dotctor 2014-11-06 19:10:09
嗯,不是这个。 – 2014-11-06 19:22:16
你可以添加一个静态方法来你的窗体的代码背后:
private static void SetTextToLabels(string text, params Label[] labels)
{
foreach (var label in labels)
{
label.Text = text;
}
}
// Use like this
private void UpdateTextInLabels()
{
SetTextToLabels("SomeText", label1, label2, label3);
}
或者,如果所有标签都在同一容器(表格,面板,等等)并且该容器中的所有标签都需要显示相同的内容,您可以在容器控件上编写扩展方法。
public static class ControlExtensions
{
public static void SetTextOnMyLabels(this Control control, string text)
{
foreach (var label in control.Controls.OfType<Label>())
{
label.Text = text;
}
}
}
// Use like this in your form
private void UpdateTextInLabels()
{
//Update all labels in panel1
panel1.SetTextOnMyLabels("SomeText");
}
您的设计时间解决方案是什么? – dotctor 2014-11-06 19:11:11
在设计时我的解决方案很简单:按住控制按钮,选择要编辑的所有标签并在属性窗口中更改其属性。即使选择了不同的控件,VS也足够聪明,只显示那些常见的属性 – 2014-11-06 19:27:40
不,只是想,每个标签都有自己的位置。如果三个标签共享相同的属性,你如何在表单上对它们进行不同的定位?它们是同一类别标签的“实例”,每个人都有自己的生活,每个人都有自己的特性。 – Steve 2014-11-06 18:02:32
如果您希望更轻松地操作多个控件,则可以将控件插入到集合中,然后将更改应用于整个列表,以便它们确切无误。另一种方法是以编程方式生成第一个控件,然后可以将该对象复制到所需的位置。 – Ckrempp 2014-11-06 18:06:21