我可以使用Windows窗体控件的多个副本吗?

时间:2014-11-06 17:58:11

标签: c# .net winforms

说,如果我使用Label我想在表单上的多个(比如三个)位置使用。我可以使用三种不同的标签,但如果我只使用一个标签的副本就会简单得多。后一种方法允许我在一个地方更改与标签相关的属性,而使用前一种方法,我必须转到三个标签中的每一个来改变它们的属性。希望我的问题很明确。

有没有办法使用同一Windows窗体控件的多个副本?

4 个答案:

答案 0 :(得分:1)

您可以将其中一个控件实例设置为“模板”,并将所有必要的属性复制到其他实例(当然,只留下位置)。

答案 1 :(得分:1)

例如,您希望标签中的文字在设计器中相同。

我们上课,说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资源(和构建)结果更改为更改LabelTextResourcedLabelText控件的所有TextResourceName控件他们的{{1}}。

这只是一个起点,您可以通过一些努力自定义此类和您想要的任何其他属性。

答案 2 :(得分:1)

正如@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));
        }
    }
}

<小时/> imgur

答案 3 :(得分:1)

您可以在表单背后添加静态方法:

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

或者,如果所有标签都在同一容器(Form,Panel等)中,并且该容器中的所有标签都需要显示相同的内容,则可以在容器控件上编写扩展方法。

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