2016-04-12 11 views
2

Ich habe eine benutzerdefinierte UITypeEditor erstellt, die ein Formular (StringSelector) startet, um eine Liste der Zeichenfolgen anzuzeigen, die der Benutzer auswählt. Das Problem ist, dass dieses Formular wissen muss, was StringManager zu verwenden hat (stringmanage ist einfach eine Klasse, die alle in einer Liste erlaubten Strings enthält).C# UITypeEditor mit Parameter

Als ich dieses Formular erstellte, übergab ich den StringManager als Parameter im Konstruktor, aber ich kann nicht herausfinden, wie ich dies mit dem UITypeEditor tun kann.

Unten ist mein aktueller Code, der einen Konstruktor verwendet, der keine Parameter hat, nur um das Formular zu zeigen, aber es gibt offensichtlich keine Zeichenfolgen, da ich die Parameterversion des Konstruktors nicht aufgerufen habe.

Wie kann ich einen Parameter an den UITypeEditor übergeben, den ich dann innerhalb der EditValue-Funktion verwenden kann? Danke vielmals.

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

mit zusätzlichem Detail AKTUALISIERT: Wie gewünscht, ich habe eine Klasse namens ControlInstance denen sich die besiedelten StringManager enthalten. Diese ControlInstance-Klasse wird an das PropertyGrid-Steuerelement und die zugehörigen Accessor-Funktionen übergeben, einschließlich der oben beschriebenen StringSelectorEditor UITypeEditor-Referenz. Hier ist ein Ausschnitt des Codes:

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

Wo ist die StringManager-Instanz gespeichert/deklariert? –

+0

Außerhalb dieser StringSelectorEditor-Klasse, aber kann von der Klasse aus aufgerufen werden, die diesen UITypeEditor verwendet. – TheGrovesy

+0

Bitte seien Sie genauer. Zeigen Sie zum Beispiel einen Beispielcode an. –

Antwort

0

EditValue Methode hat einen context Parameter, der vom Typ ITypeDescriptorContext und hat eine Instance Eigenschaft, die der Eigentümer Gegenstand der Eigenschaft, die Sie bearbeiten.

So können Sie auf öffentliche Eigenschaften in Ihrer Klasse zugreifen, indem Sie context.Instance einfach an den Typ der Eigentümerklasse übergeben. Sie können Reflektionen auch für private Mitglieder verwenden.

Beispiel

Hier ist eine Klasse, die ein List<string> in seinem Konstruktor akzeptiert, und ich werde diese Werte verwenden, wenn SomeValue Eigenschaft bearbeiten. Dazu speichere ich die übergebene Liste in einer unsichtbaren Eigenschaft SomeList und werde sie in EditValue meines benutzerdefinierten UI-Typeditors verwenden. Sie können die Liste in einer privaten Eigenschaft aufbewahren, wenn Sie möchten, und dann Werte mithilfe der Reflektion extrahieren. Hier ist eine einfache Implementierung 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; } 
} 

hier in MyUITypeEditor in EditValue Methode extrahieren I Liste Werte von context.Instance, die die Instanz des Objekts, das wir sein Eigentum bearbeiten. Dann einfach zum Beispiel I extrahierter Werte in einem Meldungsfeld zeigen:

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

es zu testen, ist es genug, um eine Instanz von MyClass in einem Eigenschaftenraster zu zeigen und versuchen SomeValue Immobilien in Immobilien Raster zu bearbeiten:

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