2011-04-22 37 views
1

我希望有一個「形式」或別的東西(不管是什麼),可以添加字符串列表組件在設計時通信

將與第一部件「StringManager」做巫婆包含字符串集合

另一方面,我想要另一個組件「ComponentReader」,它使用IExtenderProvider並在所有控件(在組件窗體上)上添加一個名爲「TheString」的屬性,讓我從字符串之一列表

因此,要清除AR:我想分享的List<String>在每個表單最少的代碼,(最具有屬性編輯器)

我不知道我怎麼能告訴「ComponentReader」在哪裏,他指的主要成分,

(我在「ComponentReader」中添加了屬性ReferedStringManager)。

是否有任何屬性或指令(或方法),以檢查項目和他引用讓所有可匹配值如「ComponentReader」性質 爲ComponentReaderReferedStringManager財產清單;

如果它不是有可能,我想靜態列表或某事的東西,也許XML文件,(但我不知道如何受孕期間管理該)

當然,所有這一切在設計時間,不在執行時間(這將是如此簡單!!)

+0

也許你應該備份,並解釋你提出的「解決方案」是爲了解決問題。這可能是另一種解決原始問題的方法。 – Tergiver 2011-04-22 15:26:45

+0

我只想學習如果我可以做到這一點...以及如何做到這一點,也許不止一個解決方案... – guillaume 2011-04-22 21:26:27

回答

1

這是一個遲到的答案,但如果你仍然感興趣,這裏是如何做到這一點。

對於您的StringManager和您的ComponentReader類都有相當多的要求。

1)這兩個類都需要從System.ComponentModel.Component派生。

2)StringManager必須重寫Component類的Site屬性。這就是「VS Designer意識到」的原因,並且可以在稍後的ComponentReader屬性中進行選擇。

3)StringManager必須公開List作爲公共屬性。爲了方便起見,在我的示例代碼bolow中,我已經在VS屬性網格中設置了EditorAttribute以實現簡單的字符串集合版本。

4)ComponentReader必須實現一個只有一個StringManager類型屬性的自定義接口。這是需求#6所需要的。

5)ComponentReader必須具有ComponentReader必須具有類型字符串的SelectedString的公共屬性類型StringManager

6)的公共屬性。我們必須將TypeConverterAttribute設置爲我們必須實現的另一個類(請參見#7)

7)我們必須實現一個StringConverter派生類。這將用於允許我們從所選的StringManager中選擇一個字符串。在這個類中,我們必須能夠通過在#4中創建的接口來檢索對ComponentReader的引用。現在

,爲代碼:

StringManager.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.ComponentModel; 
using System.Windows.Forms; 
using System.ComponentModel.Design; 

namespace VSDesignHost 
{ 
class StringManager : Component 
{ 
    private ContainerControl _containerControl = null; 

    public StringManager() 
    { 
     TheList = new List<string>(); 
    } 

    public StringManager(IContainer container) : this() 
    { 
     container.Add(this); 

     InitializeComponent(); 
    } 

    private void InitializeComponent() 
    { 
     //Whatever 
    } 

    public ContainerControl ContainerControl 
    { 
     get { return _containerControl; } 
     set { _containerControl = value; } 
    } 

    public override ISite Site 
    { 
     set 
     { 
      base.Site = value; 
      if (value != null) 
      { 
       IDesignerHost host = value.GetService(typeof(IDesignerHost)) as IDesignerHost; 
       if (host != null) 
       { 
        IComponent rootComponent = host.RootComponent; 
        if (rootComponent is ContainerControl) 
        { 
         this.ContainerControl = (ContainerControl)rootComponent; 
        } 
       } 
      } 
     } 
    } 

    [Editor("System.Windows.Forms.Design.StringCollectionEditor, System.Design", "System.Drawing.Design.UITypeEditor, System.Drawing")] 
    public List<string> TheList { get; set; } 

} 
} 

ComponentReader.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.ComponentModel; 

namespace VSDesignHost 
{ 
    class ComponentReader : Component, IStringManagerEnabled 
    { 
     private StringManager sm; 

     public ComponentReader() 
     { 
      sm = null; 
     } 

     [Browsable(true), Category("MyCategory")] 
     public StringManager StringManager 
     { 
      get { return sm; } 
      set 
      { 
       sm = value; 
      } 
     } 

     [Browsable(true), Category("MyCategory"), TypeConverter(typeof(StringManagerStringConverter))] 
     public string SelectedString { get; set; } 

    } 
} 

IStringManagerEnabled.cs:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace VSDesignHost 
{ 
    interface IStringManagerEnabled 
    { 
     StringManager StringManager 
     { 
      get; 
      set; 
     } 
    } 
} 

StringManagerStringConverter.cs:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.ComponentModel; 

namespace VSDesignHost 
{ 
    class StringManagerStringConverter : StringConverter 
    { 
     #region Make It A ComboBox 
     public override bool GetStandardValuesSupported(ITypeDescriptorContext context) 
     { 
      return true; 
     } 
     public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) 
     { 
      return false; 
     } 
     #endregion 


     #region Display Tags In List 
     public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) 
     { 
      if ((context == null) || (context.Container == null)) 
      { 
       return null; 
      } 

      Object[] Tags = this.GetTagsFromServer(context); 
      if (Tags != null) 
      { 
       return new StandardValuesCollection(Tags); 
      } 
      return null; 
     } 

     private object[] GetTagsFromServer(ITypeDescriptorContext context) 
     { 
      List<string> availableTags = new List<string>(); 

      if (context.Instance == null) 
      { 
       availableTags.Add("ITypeDescriptorContext.Instance is null"); 
       return availableTags.ToArray(); 
      } 


      IStringManagerEnabled inst = context.Instance as IStringManagerEnabled; 
      if (inst == null) 
      { 
       availableTags.Add(context.Instance.ToString()); 
       return availableTags.ToArray(); 
      } 

      if (inst.StringManager == null) 
      { 
       availableTags.Add("No StringManager selected"); 
       return availableTags.ToArray(); 
      } 

      availableTags = inst.StringManager.TheList; 
      availableTags.Sort(Comparer<string>.Default); 
      return availableTags.ToArray(); 
     } 

     #endregion 



     public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) 
     { 
      if (sourceType == typeof(string)) 
       return true; 
      return base.CanConvertFrom(context, sourceType); 
     } 

     public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) 
     { 
      if (value is string) 
       return value.ToString(); 
      return base.ConvertFrom(context, culture, value); 
     } 

    } 
} 

創建一個Windows Forms項目,將這些文件添加到它,並生成項目。

現在,在您的窗體上,您可以通過從工具箱中拖動來添加每個StringManager和ComponentReader的實例。

選擇StringManager,並在屬性中使用字符串集合編輯器向TheList添加一些字符串。

選擇ComponentReader,並在屬性窗口中,您應該能夠從下拉列表中選擇您的StringManager實例。

您現在應該可以從SelectedString的下拉列表中選擇一個字符串。

我希望你喜歡

呂克