2016-04-12 100 views
2

我創建了一個自定義UITypeEditor,它啓動一個窗體(StringSelector)來顯示用戶從中選擇的字符串列表。問題是這個表單需要知道使用什麼StringManager(stringmanage只是一個包含List中允許的所有字符串的類)。帶參數的C#UITypeEditor

當我創建這個表單時,我在構造函數中傳入了StringManager作爲參數,但是我無法弄清楚如何使用UITypeEditor做到這一點。

下面是我目前的代碼,它使用一個沒有參數的構造函數,只是爲了讓表單顯示,但顯然沒有字符串,因爲我沒有調用構造函數的參數版本。

如何將參數傳遞給UITypeEditor然後我可以在EditValue函數中使用?非常感謝。

class StringSelectorEditor : UITypeEditor 
{ 
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) 
    { 
     return UITypeEditorEditStyle.Modal; 
    } 

    public override object EditValue(ITypeDescriptorContext context, System.IServiceProvider provider, object value) 
    { 
     IWindowsFormsEditorService svc = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService; 

     StringItem item = value as StringItem; 

     if (svc != null) 
     { 
      // ###### How do I pass a reference to this EditValue function so that I can.... 
      using (StringSelector form = new StringSelector(/* ... INSERT IT HERE */)) 
      { 
       form.Value = item; 
       if (svc.ShowDialog(form) == DialogResult.OK) 
       { 
        item = form.Value; // update object 
       } 
      } 
     } 
     return value; // can also replace the wrapper object here 
    } 
} 

更新,添加了細節: 按照要求,我有一個名爲ControlInstance類,它本身就包含着人口StringManager。正是這個ControlInstance類傳遞給PropertyGrid控件及其訪問器函數,包括上述的StringSelectorEditor UITypeEditor引用。下面是代碼的一個片段:

public class ControlInstance_Label : ControlInstance 
{ 
    StringManager stringManager; 
    string thisName = ""; 
    StringItem linkedStringItem; 

    public ControlInstance_Label(String TextFilePath) 
    { 
     // Code here which populates the StringManager with text from the above file 
    } 

    [Category("Design"), Description("Control Name")] 
     public String Name 
     { 
      get { return thisName; } 
      set { thisName = value; } 
     } 

    // THIS IS WERE I SOMEHOW NEED TO PASS IN THE StringManager Ref to the EditValue function of the custom UITypeEditor 
    [Category("Design"), Description("Static String Linked to this Control")] 
     [Editor(typeof(StringSelectorEditor), typeof(UITypeEditor))] 
     public StringItem LinkedString 
     { 
      get { return linkedStringItem; } 
      set { linkedStringItem = value; } 
     } 
} 
+0

你在哪裏存儲/聲明瞭StringManager實例? –

+0

以外的StringSelectorEditor類,但可以從使用此UITypeEditor的類訪問。 – TheGrovesy

+0

請更準確。舉例說明一些示例代碼。 –

回答

0

EditValue方法具有context參數是ITypeDescriptorContext類型的,並且具有一個Instance屬性是正在編輯的屬性的所有者對象。

因此,只需將context.Instance轉換爲所有者類類型,即可訪問課程中的任何公共屬性。你也可以使用反射訪問私人成員。

下面是在構造函數接受List<string>一類,我將使用這些值編輯SomeValue屬性時。爲此,我將傳遞的列表存儲在一個不可見的屬性SomeList中,並將在我的自定義UI類型編輯器的EditValue中使用它。如果您喜歡,可以將列表保留在私有屬性中,然後使用反射提取值。下面是一個簡單MyClass實現:

public class MyClass 
{ 
    [Browsable(false)] 
    public List<String> SomeList { get; set; } 
    public MyClass(List<String> list) 
    { 
     SomeList = list; 
    } 

    [Editor(typeof(MyUITypeEditor), typeof(UITypeEditor))] 
    public string SomeValue { get; set; } 
} 

這裏在EditValue方法MyUITypeEditor,我從context.Instance這是我們正在編輯其屬性的對象實例提取列表值。然後就比如我顯示一個消息框提取的值:

public class MyUITypeEditor : UITypeEditor 
{ 
    public override object EditValue(ITypeDescriptorContext context, 
     IServiceProvider provider, object value) 
    { 
     //Just as an example, show a message box containing values from owner object 
     var list = ((MyClass)context.Instance).SomeList; 
     MessageBox.Show(string.Format("You can choose from {0}.", 
      string.Join(",", list))); 

     return base.EditValue(context, provider, value); 
    } 
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) 
    { 
     return UITypeEditorEditStyle.Modal; 
    } 
} 

爲了測試它,這是不夠的屬性網格顯示的MyClass一個實例,並且嘗試在屬性網格編輯SomeValue屬性:

var myObject = new MyClass(new List<string>() { "A", "B", "C" }); 
this.propertyGrid1.SelectedObject = myObject;