PropertyGrid display Textbox inline, not as a dropdown
See the question and my original answer on StackOverflowYou could use a TypeConverter that would restrict the text once it's been entered. That would work only the textbox looses the focus. Let's suppose I have this class I want to edit using the property grid:
public class MyClass
{
[TypeConverter(typeof(MyTypeConverter))]
public string MyText { get; set; }
}
Here is a type converter code that does this:
public class MyTypeConverter : TypeConverter
{
public const int MaxLength = 10;
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return destinationType == typeof(string);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
return Truncate(value as string, MaxLength);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
return Truncate(value as string, MaxLength);
}
private static string Truncate(string value, int maxLength)
{
if (value == null)
return null;
return value.Length <= maxLength ? value : value.Substring(0, maxLength);
}
}
Otherwise, you can hack the grid, like I demonstrate here. It's not a UITypeEditor because the underlying textbox is shared for all items. The following approach is based on selection events. Again, this is another class I want to edit:
public class MyClass
{
[Editor(typeof(NoneEditor), typeof(UITypeEditor))]
public string MyText { get; set; }
public string MyOtherText { get; set; }
}
Note the MyText property is decorated with a "marker" editor that just does nothing:
public class NoneEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.None;
}
}
I can just hook the grid, like this:
propertyGrid1.SelectedGridItemChanged += OnPropertyGridSelectedGridItemChanged;
public static void OnPropertyGridSelectedGridItemChanged(object sender, SelectedGridItemChangedEventArgs e)
{
PropertyGrid pg = (PropertyGrid)sender;
GridItem item = e.NewSelection;
// yes, a grid item is also an IServiceProvider
IServiceProvider sp = (IServiceProvider)item;
// get the property grid view control
IWindowsFormsEditorService svc = (IWindowsFormsEditorService)sp.GetService(typeof(IWindowsFormsEditorService));
// WARNING: hack time! this uses private members, so use at your own risks...
TextBox edit = (TextBox)svc.GetType().GetProperty("Edit", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(svc, null);
// is this our funky stuff?
if (item.PropertyDescriptor.GetEditor(typeof(UITypeEditor)) is NoneEditor)
{
edit.MaxLength = 10;
edit.BackColor = Color.Blue;
}
else // don't forget to reset the edit box here
{
edit.MaxLength = int.MaxValue;
edit.BackColor = Color.White;
}
}