2014-11-06 100 views
1

說,如果我正在使用一個Label,我想在一個窗體上的多個(如三個)位置使用。我可以使用三個不同的標籤,但如果我只能使用一個標籤的副本,它會簡單得多。後一種方法將允許我在一個地方更改與標籤相關的屬性,而使用前一種方法時,我必須去三個標籤中的每一個來更改它們的屬性。希望我的問題很明確。我可以使用Windows窗體控件的多個副本嗎?

有沒有辦法使用同一個Windows窗體控件的多個副本?

+1

不,只是想,每個標籤都有自己的位置。如果三個標籤共享相同的屬性,你如何在表單上對它們進行不同的定位?它們是同一類別標籤的「實例」,每個人都有自己的生活,每個人都有自己的特性。 – Steve 2014-11-06 18:02:32

+1

如果您希望更輕鬆地操作多個控件,則可以將控件插入到集合中,然後將更改應用於整個列表,以便它們確切無誤。另一種方法是以編程方式生成第一個控件,然後可以將該對象複製到所需的位置。 – Ckrempp 2014-11-06 18:06:21

回答

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資源(和構建)結果改爲所有人的LabelTextResourced控件,其LabelTextTextResourceName

這只是一個起點,您可以通過一些努力來自定義此類和任何其他屬性。

+1

+1作爲創意答案。我有一個問題:你將如何在運行時更新這個...? – 2014-11-06 18:47:55

+0

這是一個全新的問題,您可以在運行時編輯資源文件,但這些更改不會反映在您的控件中,我認爲提供一種從資源文件中再次獲取值的方法將解決問題@ Ric.Net – dotctor 2014-11-06 18:53:33

1

您可以將其中一個控件實例設置爲「模板」並將所有必要的屬性複製到其他實例(當然,只留下那些位置)。

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

+0

以及什麼是解決方案設計時間? – dotctor 2014-11-06 19:10:09

+0

嗯,不是這個。 – 2014-11-06 19:22:16

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

或者,如果所有標籤都在同一容器(表格,面板,等等)並且該容器中的所有標籤都需要顯示相同的內容,您可以在容器控件上編寫擴展方法。

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

您的設計時間解決方案是什麼? – dotctor 2014-11-06 19:11:11

+0

在設計時我的解決方案很簡單:按住控制按鈕,選擇要編輯的所有標籤並在屬性窗口中更改其屬性。即使選擇了不同的控件,VS也足夠聰明,只顯示那些常見的屬性 – 2014-11-06 19:27:40

相關問題