C# PropertyGrid自定义UserControl项不可编辑实现

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:

One Response to “C# PropertyGrid自定义UserControl项不可编辑实现”

  1. ghl说道:

    实现SelectControl的UserControl,提供Selected属性,做一些操作。
    是什么意思,不很明白~

    lordong 于 2008-11-6 11:10:38 回复

    “定义Editor”部分不是有一块代码是这样的吗:
    SelectControl ctrl = new SelectControl();
    if (value is ItemContent)
    {
    ctrl.Selected = (value as ItemContent).Content;
    }
    service.DropDownControl(ctrl);
    (value as ItemContent).Content = ctrl.Selected;
    也就是说UserControl与Editor是通过Selected属性来交互数据的,“SelectControl”是一个UserControl的例子,“Selected”也是这个UserControl的属性例子,你可以根据自己的情况用不同的名字,我这个例子的Selected属性就是一个ItemContent对象。
    当你点开UserControl后是不是可以操作了,输入、选中等等,这就是“做一些操作”了。

Leave a Reply