Winforms PropertyGrid: how do I allow free form text, and a modal dialog for editing a property?
See the question and my original answer on StackOverflowYou can use a TypeConverter that supports string
conversion for this. For example, here is a TypeConverter for a property of Encoding type, that would be declared like this:
public class MyClass
{
...
[TypeConverter(typeof(EncodingConverter))]
public Encoding MyEncoding { get; set; }
...
}
/// <summary>
/// Provides a type converter to convert Encoding objects to and from various other representations.
/// </summary>
public class EncodingConverter: TypeConverter
{
/// <summary>
/// Returns whether this converter can convert an object of the given type to the type of this converter, using the specified context.
/// </summary>
/// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"/> that provides a format context.</param>
/// <param name="sourceType">A <see cref="T:System.Type"/> that represents the type you want to convert from.</param>
/// <returns>
/// true if this converter can perform the conversion; otherwise, false.
/// </returns>
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return ((typeof(string) == sourceType) || base.CanConvertFrom(context, sourceType));
}
/// <summary>
/// Returns whether this converter can convert the object to the specified type, using the specified context.
/// </summary>
/// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"/> that provides a format context.</param>
/// <param name="destinationType">A <see cref="T:System.Type"/> that represents the type you want to convert to.</param>
/// <returns>
/// true if this converter can perform the conversion; otherwise, false.
/// </returns>
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return ((typeof(string) == destinationType) || base.CanConvertTo(context, destinationType));
}
/// <summary>
/// Converts the given object to the type of this converter, using the specified context and culture information.
/// </summary>
/// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"/> that provides a format context.</param>
/// <param name="culture">The <see cref="T:System.Globalization.CultureInfo"/> to use as the current culture.</param>
/// <param name="value">The <see cref="T:System.Object"/> to convert.</param>
/// <returns>
/// An <see cref="T:System.Object"/> that represents the converted value.
/// </returns>
/// <exception cref="T:System.NotSupportedException">
/// The conversion cannot be performed.
/// </exception>
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (!(value is string))
return base.ConvertFrom(context, culture, value);
string name = (string)value;
if (name == null)
return null;
return Encoding.GetEncoding(name);
}
/// <summary>
/// Converts the given value object to the specified type, using the specified context and culture information.
/// </summary>
/// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"/> that provides a format context.</param>
/// <param name="culture">A <see cref="T:System.Globalization.CultureInfo"/>. If null is passed, the current culture is assumed.</param>
/// <param name="value">The <see cref="T:System.Object"/> to convert.</param>
/// <param name="destinationType">The <see cref="T:System.Type"/> to convert the <paramref name="value"/> parameter to.</param>
/// <returns>
/// An <see cref="T:System.Object"/> that represents the converted value.
/// </returns>
/// <exception cref="T:System.ArgumentNullException">
/// The <paramref name="destinationType"/> parameter is null.
/// </exception>
/// <exception cref="T:System.NotSupportedException">
/// The conversion cannot be performed.
/// </exception>
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if ((typeof(string) == destinationType) && (value is Encoding))
{
Encoding encoding = (Encoding)value;
return encoding.HeaderName;
}
return base.ConvertTo(context, culture, value, destinationType);
}
}