C#的PropertyGrid控件支持给属性项自定义Converter和Editor,当指定从TypeConverter派生的Converter时可以只能从下拉列表中选择,即属性值不可手工编辑,但不支持UserControl;而指定从UITypeEditor派生的Editor可以支持UserControl但又没办法限制用户直接编辑属性值。
有时我们需要实现既能从UserControl中设定值又不想让用户直接编辑,就象一些Collection一样,只显示"(Collection)"串不可编辑又可以通过下拉或弹出窗体让用户选择。经过多次实现,发现属性项同时指定自定义Converter和Editor可以解决这个问题,后面附一些实现代码。
定义属性项:
private ItemContent _itemContent = new ItemContent();
[EditorAttribute(typeof(ContentEditor), typeof(UITypeEditor)),
TypeConverterAttribute(typeof(ConentConverter)),
DescriptionAttribute("Select item content")]
public ItemContent Content
{
get { return _itemContent; }
set { _itemContent = value; }
}
定义属性内容类:
public class ItemContent
{
private string _type = "Type";
private string _content = "Content";
public string Type
{
get { return _type; }
}
public string Content
{
get { return _content; }
set { _content = value; }
}
}
定义Converter:
public class ConentConverter : ExpandableObjectConverter
{
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
{
return true;
}
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
{
return true;
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(ItemContent))
{
return true;
}
return base.CanConvertTo(context, destinationType);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(System.String) &&
value is ItemContent)
{
return "(Collection)";
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
定义Editor:
public class ContentEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.DropDown;
}
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
IWindowsFormsEditorService service = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
SelectControl ctrl = new SelectControl();
if (value is ItemContent)
{
ctrl.Selected = (value as ItemContent).Content;
}
service.DropDownControl(ctrl);
(value as ItemContent).Content = ctrl.Selected;
return value;
}
}
实现SelectControl的UserControl,提供Selected属性,做一些操作。
最后将包含有ItemContent属性的类对象赋给PropertyGrid的SelectedObject即可。
Tags: C#/.NET
实现SelectControl的UserControl,提供Selected属性,做一些操作。
是什么意思,不很明白~