具有参数的C#UITypeEditor [英] C# UITypeEditor with Parameter

查看:315
本文介绍了具有参数的C#UITypeEditor的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个自定义的UITypeEditor,它将启动一个窗体(StringSelector)以显示用户从中选择的字符串列表.问题在于此表单需要知道要使用哪种StringManager(stringmanage只是一个类,其中包含List中允许的所有字符串).

I have created a custom UITypeEditor which launches a form (StringSelector) to display a list of strings which the user choses from. The problem is that this form needs to know what StringManager to use (stringmanage is simply a class which contains all the strings allowed in a List).

创建此表单时,我将StringManager作为构造函数中的参数传入,但是我无法弄清楚如何使用UITypeEditor做到这一点.

When I created this form I was passing in the StringManager as a parameter in the Constructor, but I cannot work out how i can do this with the UITypeEditor.

下面是我当前的代码,该代码使用没有参数的构造函数,只是为了显示表单,但是显然没有字符串,因为我没有调用构造函数的参数版本.

Below is my current code which uses a constructor which has no parameters, just to get the form to show, however there are obviously no strings as I didn't call the parameter version of the constructor.

如何将参数传递给UITypeEditor,然后可以在EditValue函数中使用它?非常感谢.

How can I pass a parameter to the UITypeEditor which I can then use within the EditValue function? Many thanks.

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参考.这是代码段:

UPDATED with additional detail: As requested, I have a class called ControlInstance which itself contains the populated StringManager. It is this ControlInstance Class which is passed to the PropertyGrid control and its accessor functions displayed in it including the above described StringSelectorEditor UITypeEditor reference. Here is a snippet of the code:

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参数,该参数的类型为 Instance 属性,它是您正在编辑的属性的所有者对象.

EditValue method has a context parameter which is of type ITypeDescriptorContext and has an Instance property which is the owner object of the property that you are editing.

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

So you can have access to any public properties in your class by simply casting context.Instance to the owner class type. Also you can use reflection to have access to private members as well.

示例

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

Here is a class that accepts a List<string> in its constructor and I'm going to use those values when editing SomeValue property. To do so, I store the passed list in an invisible property SomeList and will use it in EditValue of my custom UI type editor. You can keep the list in a private property if you like and then extract values using reflection. Here is a simple MyClass implementation:

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中提取列表值,该值是我们正在编辑其属性的对象的实例.然后,例如,我在消息框中显示提取的值:

Here in MyUITypeEditor in EditValue method, I extract list values from context.Instance which is the instance of the object which we are editing its property. Then just for example I show extracted values in a message box:

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属性:

To test it, it's enough to show an instance of MyClass in a property grid and try to edit SomeValue property in property grid:

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

这篇关于具有参数的C#UITypeEditor的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆