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

时间:2021-07-30 21:10:57

Say, if I were using a Label that I want to use at multiple (say three) places on a form. I could use three different labels but it would be much simpler if I could just use copies of one label. This latter approach would allow me to change properties related to the labels at one place, while with the former approach I'd have to go to each of the three labels to change their properties. Hopefully, my question is clear.

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

Is there a way to use multiple copies of the same Windows Forms Control?

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

4 个解决方案

#1


1  

For example, you want to have labels that their text are same in your designer.

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

We make a class, say LabelTextResourced

我们创建了一个类,比如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.
        }
    }
}

Build your project, now you can add LabelTextResourced control to your designer.

构建项目,现在可以将LabelTextResourced控件添加到设计器中。

Right click your project and go to properties and select resource tab. add a resource for example: {Name: "LabelText", Value: "Hiiiiii!!!"}

右键单击您的项目,然后转到属性并选择资源选项卡。添加资源,例如:{Name:“LabelText”,Value:“Hiiiiii !!!”}

Now, go back to form designer, select your instance of LabelTextResourced and set it's TextResourceName property to LabelText.

现在,返回表单设计器,选择LabelTextResourced实例并将其TextResourceName属性设置为LabelText。

Build again and now you should see that your label text is set from the resource. Now you can have many label that their text are all set from one location and changing the LabelText resource (and a build) results to changing of all of you LabelTextResourced controls that have LabelText as their TextResourceName.

再次构建,现在您应该看到您的标签文本是从资源设置的。现在,您可以拥有许多标签,其文本都是从一个位置设置的,并将LabelText资源(和构建)结果更改为更改所有LabelTextResourced控件,这些控件将LabelText作为其TextResourceName。

This is just a starting point, you can customize this class and any other properties you want with some effort.

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

#2


1  

You could set one of the control instance as a 'template' and copy all necessary properties to other instances (of course, leave there positions alone).

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

#3


1  

As @nim suggested, you could create a property mapper. Of course, in design-time, things might look ugly. For example:

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


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

#4


1  

You could add a static method to your form's code behind:

您可以在表单的代码后面添加一个静态方法:

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

Or if all labels are in the same container (Form, Panel, etc.) and all labels in that container need to display the same you could write an extension method on the container control.

或者,如果所有标签都在同一个容器(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");
}

#1


1  

For example, you want to have labels that their text are same in your designer.

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

We make a class, say LabelTextResourced

我们创建了一个类,比如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.
        }
    }
}

Build your project, now you can add LabelTextResourced control to your designer.

构建项目,现在可以将LabelTextResourced控件添加到设计器中。

Right click your project and go to properties and select resource tab. add a resource for example: {Name: "LabelText", Value: "Hiiiiii!!!"}

右键单击您的项目,然后转到属性并选择资源选项卡。添加资源,例如:{Name:“LabelText”,Value:“Hiiiiii !!!”}

Now, go back to form designer, select your instance of LabelTextResourced and set it's TextResourceName property to LabelText.

现在,返回表单设计器,选择LabelTextResourced实例并将其TextResourceName属性设置为LabelText。

Build again and now you should see that your label text is set from the resource. Now you can have many label that their text are all set from one location and changing the LabelText resource (and a build) results to changing of all of you LabelTextResourced controls that have LabelText as their TextResourceName.

再次构建,现在您应该看到您的标签文本是从资源设置的。现在,您可以拥有许多标签,其文本都是从一个位置设置的,并将LabelText资源(和构建)结果更改为更改所有LabelTextResourced控件,这些控件将LabelText作为其TextResourceName。

This is just a starting point, you can customize this class and any other properties you want with some effort.

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

#2


1  

You could set one of the control instance as a 'template' and copy all necessary properties to other instances (of course, leave there positions alone).

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

#3


1  

As @nim suggested, you could create a property mapper. Of course, in design-time, things might look ugly. For example:

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


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

#4


1  

You could add a static method to your form's code behind:

您可以在表单的代码后面添加一个静态方法:

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

Or if all labels are in the same container (Form, Panel, etc.) and all labels in that container need to display the same you could write an extension method on the container control.

或者,如果所有标签都在同一个容器(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");
}