views:

33

answers:

2

Using the CreateInstance method of the TypeConverter class, it's possible to edit the properties of an immutable object - such as a font.

However, unlike the font class, there's some properties in my class that i'd like to be browsable but readonly - even though CreateInstance is supported.

Is there an attribute that supports this?

ETA: I've answered the question below. There's still room for a slight improvement, though, if anyone has any ideas.

+1  A: 

TypeConverter.CreateInstance() does not change the properties of, say, the Font class. It just creates a new instance of it. There's no magic here, it just uses the class constructor.

Just omit the property setter, you'll be fine.

If you want to prevent anybody from using Reflection to poke your private fields then you'll need to use the [ReflectionPermission] attribute.

Hans Passant
Hi, I realise that's how the fontconverter works, and that's how my converter works. All the fields in my class are already read only. Implementing CreateInstance allows those readonly props to be changed and then a new instance can be created. However, there's a property 'Name' that i want to remain readyonly but browsable. Actually, I've just realised how to do it. Attach a type converter to the fields, that I want ready only, and override so that it can't convert from string.
Jules
A: 

To make a property readonly, inherit the type converter and override the CanConvertFrom method. Eg:

Public Class ReadOnlyStringConverter
    Inherits StringConverter

    Public Overrides Function CanConvertFrom(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal sourceType As System.Type) As Boolean
        Return (sourceType IsNot GetType(String)) AndAlso MyBase.CanConvertFrom(context, sourceType)
    End Function

End Class

The only down side is that the text does not appear read-only, so one might expect to be able to edit it.

If it's a one off, it's fine to nest the class and make it private so that it doesn't clutter up your intellisense.

To disable an editor, add the following attribute:

<Editor(GetType(UITypeEditor), GetType(UITypeEditor))> _

It's not enough to add:

<Editor()> _

If you do, then the existing editor will still be picked up.

Jules