How do I inject a custom UITypeEditor for all properties of a closed-source type?

Cat Zimmermann picture Cat Zimmermann · May 11, 2009 · Viewed 9k times · Source

I want to avoid placing an EditorAttribute on every instance of a certain type that I've written a custom UITypeEditor for.

I can't place an EditorAttribute on the type because I can't modify the source.

I have a reference to the only PropertyGrid instance that will be used.

Can I tell a PropertyGrid instance (or all instances) to use a custom UITypeEditor whenever it encounters a specific type?

Here is an MSDN article that provides are starting point on how to do this in .NET 2.0 or greater.

Answer

Marc Gravell picture Marc Gravell · May 11, 2009

You can usually associate editors etc at runtime via TypeDescriptor.AddAttributes. For example (the Bar property should show with a "..." that displays "Editing!"):

using System;
using System.ComponentModel;
using System.Drawing.Design;
using System.Windows.Forms;

class Foo
{
    public Foo() { Bar = new Bar(); }
    public Bar Bar { get; set; }
}
class Bar
{
    public string Value { get; set; }
}

class BarEditor : UITypeEditor
{
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
        return UITypeEditorEditStyle.Modal;
    }
    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {
        MessageBox.Show("Editing!");
        return base.EditValue(context, provider, value);
    }
}
static class Program
{
    [STAThread]
    static void Main()
    {
        TypeDescriptor.AddAttributes(typeof(Bar),
            new EditorAttribute(typeof(BarEditor), typeof(UITypeEditor)));
        Application.EnableVisualStyles();
        Application.Run(new Form { Controls = { new PropertyGrid { SelectedObject = new Foo() } } });
    }
}