This question (How to create a PropertyGrid editor that limits a string to n characters)几乎完全符合我的需要,但我不想使用下拉列表,而是希望编辑在网格本身中发生。
UITypeEditorEditStyle
似乎没有多大帮助,因为将其设置为None会完全消除文本框控件。
或者,是否有更简单的方法来访问控件用于挂钩事件的TextBox?
最终,我正在寻找一个文本输入小部件,它限制输入的内容1.完成内联,以及2.无需等到用户停止输入以给出错误或截断输入。
答案 0 :(得分:2)
您可以使用TypeConverter,一旦输入文本就会限制文本。这只会使文本框失去焦点。让我们假设我有这个类,我想用属性网格编辑:
public class MyClass
{
[TypeConverter(typeof(MyTypeConverter))]
public string MyText { get; set; }
}
以下是执行此操作的类型转换器代码:
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);
}
}
否则,你可以破解网格,就像我在这里演示的那样。它不是UITypeEditor,因为底层文本框是为所有项共享的。以下方法基于选择事件。同样,这是我要编辑的另一个类:
public class MyClass
{
[Editor(typeof(NoneEditor), typeof(UITypeEditor))]
public string MyText { get; set; }
public string MyOtherText { get; set; }
}
请注意,MyText属性使用&#34;标记&#34;编辑什么都不做:
public class NoneEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.None;
}
}
我可以像这样挂钩网格:
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;
}
}