Additional data in UITypeEditor EditValue

889 views Asked by At

I have some problems accessing contextual data in a custom UITypeEditor. I'm using a PropertyGrid to display some settings using Windows Forms. The SelectedObject of the PropertyGrid contains a List<A>. Type A has a property for which I have created a custom editor that needs some external information to be able to customize it for different instances of PropertyGrid.

I've attempted the approach of using the IServiceProvider passed to EditValue to access a custom service that contains the data. It was suggested by ironic in an answer here Passing objects to a UITypeEditor but I haven't managed to get it to work. GetService always returns null inside EditValue. I think my problem is that the ISite I set as PropertyGrid.Site isn't reachable in the nested UITypeEditor where the information is needed (when I attempt to get the service using GetService inside the list's editor's EditValue method it works).

Does anyone know how to make my ISite propagate to nested UITypeEditors?

Some pseudo code:

public interface IMyService {
    object GetUserData();
}

public class MyService : IMyService {
    private object userData;
    public MyService(object ud) {
        userData = ud;
    }

    public object GetUserData() {
        return userData ;
    }
}

public class MySite : ISite {
    private object userData;

    public MySite(object ud) {
        userData = o;
    }

    ...

    public object GetService(Type serviceType) {
        if (serviceType == typeof(IMyService))
        {
            return (IMyService) new MyService(userData);
        }
        else
        {
            return null;
        }
    }
}

public class A {
    [Editor(typeof(EditorA), typeof(UITypeEditor)]
    public object SomeEditedProperty { ... }
}



public EditorA : UITypeEditor {
    ...
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
        return UITypeEditorEditStyle.Modal;
    }
    ...
    public override object EditValue(ITypeDescriptorContext c, IServiceProvider p, object v) {
        // This always returns null!
        object myService = p.GetService(typeof(IMyService));  
        ...
        object myData = myService.GetUserData();
        ...
    }
}

public class EditedObject {
    [Editor(...)]
    public List<A> Stuff { ... }
}

// somewhere
object userData = new object();
propertyGrid.Site = new MySite(userData);

EditedObject objectToEdit = new EditedObject();
...
propertyGrid.SelectedObject = objectToEdit;
0

There are 0 answers