C# UITypeEditor with Parameter

时间秒杀一切 提交于 2019-12-22 19:01:33

问题


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).

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.

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

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

回答1:


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.

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.

Example

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

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

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;


来源:https://stackoverflow.com/questions/36577901/c-sharp-uitypeeditor-with-parameter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!