See the question and my original answer on StackOverflow

One solution is to declare a TypeConverter that does ... nothing, something like this:

This is the class you want to edit:

public class MyClass
{
    [Editor(typeof(MyClassEditor), typeof(UITypeEditor))]
    [TypeConverter(typeof(MyConverter))]
    public string MyProperty { get; set; }
}

This is the custom UITypeEditor:

public class MyClassEditor : UITypeEditor
{
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
        return UITypeEditorEditStyle.Modal;
    }

    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {
        MessageBox.Show("press ok to continue");
        return "You can't edit this";
    }
}

This is the famous converter that took me days to write:

// this class does nothing on purpose
public class MyConverter : TypeConverter
{
}