带参数的C#UITypeEditor

我创建了一个自定义UITypeEditor ,它启动一个表单(StringSelector)来显示用户选择的字符串列表。 问题是这个表单需要知道要使用的StringManager(stringmanage只是一个包含List中允许的所有字符串的类)。

当我创建这个表单时,我将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; } } } 

EditValue方法具有一个context参数, ITypeDescriptorContext参数的类型为ITypeDescriptorContext并且具有Instance属性,该属性是您正在编辑的属性的所有者对象。

因此,只需将context.Instance转换为所有者类类型,即可访问类中的任何公共属性。 您也可以使用reflection来访问私有成员。

这是一个在其构造函数中接受List的类,我将在编辑SomeValue属性时使用这些值。 为此,我将传递的列表存储在一个不可见的属性SomeList ,并将在我的自定义UI类型编辑器的EditValue中使用它。 如果您愿意,可以将列表保留在私有属性中,然后使用reflection提取值。 这是一个简单的MyClass实现:

 public class MyClass { [Browsable(false)] public List SomeList { get; set; } public MyClass(List 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() { "A", "B", "C" }); this.propertyGrid1.SelectedObject = myObject;