PropertyGrid使用


很早之前写的一个例子,近期看到了,就简单记录下。
PropertyGrid控件是Visual Studio开发工具里面的属性浏览器,我们在VS里面可以通过属性浏览器查看,修改控件的属性。

选择对象

要标识 PropertyGrid 显示的内容,需将 PropertyGrid.SelectedObject 属性设置为一个对象实例。
然后,PropertyGrid 将完成其余的工作。每次设置 SelectedObject 时,PropertyGrid 都会刷新显示的属性。
这提供了一种简单的方法来强制刷新属性,或在运行时切换对象。您还可以调用 PropertyGrid.Refresh 方法来刷新属性。
创建一个 AppSettings 对象,并将其设置为 PropertyGrid.SelectedObject 属性的值。
 AppSetting setting = new AppSetting();
 this.propertyGrid.SelectedObject = setting;

属性描述

DescriptionAttribute:设置显示在属性下方说明帮助窗格中的属性文本
CategoryAttribute:设置属性在网格中所属的类别
Browsable:在网格中是否显示属性
ReadOnly:设置属性只读
DefaultValue:表示属性的默认值,修改值之后,字体会加粗黑体

普通属性

 	    private int _width = 10;
        [Browsable(true)]
        [Category("简单属性")]
        [Description("设置整型")]
        [DefaultValue(10)]
        public int Width
        {
            get { return _width; }
            set { _width = value; }
        }
        private string _name = "Jack";
        [Category("简单属性")]
        [Description("设置字符串")]
        [DefaultValue("Jack")]
        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }
        private Size _windowSize = new Size(100, 100);
        [Browsable(true)]
        [Category("简单属性")]
        [Description("窗体尺寸")]
        public Size WindowSize
        {
            get
            {
                return _windowSize;
            }
            set
            {
                _windowSize = value;
            }
        }
       private Font _windowFont = new Font("宋体", 9, FontStyle.Regular);
        [Browsable(true)]
        [Category("简单属性")]
        [Description("字体")]
        public Font Font
        {
            get
            {
                return _windowFont;
            }
            set
            {
                _windowFont = value;
            }
        }
        private Color _color = SystemColors.Control;
        [Browsable(true)]
        [Category("简单属性")]
        [Description("颜色")]
        public Color Color
        {
            get
            {
                return _color;
            }
            set
            {
                _color= value;
            }
        }

具体效果如下:
在这里插入图片描述

下拉列表

    //性别枚举类
    public enum Sex
    {
        male = 1,
        female = 2
    }
        private Sex _sex = Sex.male;
        [Browsable(true)]
        [Category("简单属性")]
        [DescriptionAttribute("枚举")]
        [DefaultValue(Sex.male)]
        public Sex Sex 
        {
            get
            {
                return _sex;
            }
            set
            {
                _sex = value;
            }
        }

具体效果如下:
在这里插入图片描述

自定义下拉列表

        private string _defaultFileName = string.Empty;
        [Category("下拉列表")]
        [Description("自定义下拉列表")]
        [Browsable(true)] 
        [TypeConverter(typeof(FileNameConverter))]
        public string DefaultFileName
        {
            get
            {
                return _defaultFileName;
            }
            set
            {
                _defaultFileName = value;
            }
        }
    /// <summary>
    /// 创建一个继承自定义转换器类的类,由于DefaultFileName属性是String类型,因此可以从StringConverter继承。
    /// 如果属性类型的类型转换器不存在,
    /// 则可以继承TypeConverter
    /// </summary>
    public class FileNameConverter:StringConverter
    {
        /// <summary>
        /// 重写GetStandardValuesSupported方法并返回true.
        /// 以指示此对象支持可从列表中选取的一组标准值。
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
        {
            return true;
        }

        /// <summary>
        /// 检索一个集合,该集合包含适用于此验证程序的数据类型的标准值集。 如果该数据类型不支持标准值集,这将返回 null。
        /// </summary>
        /// <param name="context">格式化程序上下文</param>
        /// <returns>包含 null 或标准有效值集的集合</returns>
        public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
        {
            StandardValuesCollection collection = new StandardValuesCollection(new String[] { "诸葛亮", "诸葛暗", "诸葛孔明", });
            return collection;
        }

        //@! true: disable text editting.    false: enable text editting;
        public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
        {
            return true;//true下拉框不可编辑
        } 
    }

具体效果入下:
在这里插入图片描述

折叠列表

要使 PropertyGrid 能够展开 SpellingOptions 属性,您需要创建 TypeConverter 。	
TypeConverter 提供了从一种类型转换为另一种类型的方法。
PropertyGrid 使用 TypeConverter 将对象类型转换为 String ,并使用该 String 在网格中显示对象值。
在编辑过程中,TypeConverter 会将 String 转换回对象类型。
.NET 框架提供的 ExpandableObjectConverter 类可以简化这一过程。 
        private SpellingOptions _spellingOptions = new SpellingOptions();
        [Category("折叠列表")]
        [Browsable(true)]
        public SpellingOptions SpellingOptions
        {
            get
            {
                return _spellingOptions;
            }
            set
            {
                _spellingOptions = value;
            }
        }
    /// <summary>
    /// 折叠列表元素
    /// </summary>
    [Description("展开查看应用程序的拼写选项")]
    [TypeConverter(typeof(SpellingOptionsConverter))]
    public class SpellingOptions
    {
        private bool isOne = true;
        private bool isTwo = false;
        private bool isThree = true;

        [DefaultValue(true)]
        public bool IsOne
        {
            get
            {
                return isOne;
            }
            set
            {
                isOne = value;
            }
        }

        [DefaultValue(false)]
        public bool IsTwo
        {
            get
            {
                return isTwo;
            }
            set
            {
                isTwo = value;
            }
        }

        [DefaultValue(false)]
        public bool IsThree
        {
            get
            {
                return isThree;
            }
            set
            {
                isThree = value;
            }
        }
    }
    /// <summary>
    /// 自定义类型转换器 
    /// 所有继承TypeConverter必须实现的虚方法:
    /// (1)CanConverterTo
    /// (2)ConverterTo
    /// </summary>
    public class SpellingOptionsConverter: ExpandableObjectConverter
    {
        /// <summary>
        /// 有一个Type参数(要转换成什么类型),例如要设计成转换成string,在方法体里面判断这个参数的Type如果是string,返回true,否则为false;
        /// </summary>
        /// <param name="context"></param>
        /// <param name="destinationType"></param>
        /// <returns></returns>
        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            if (destinationType == typeof(SpellingOptions))
            {
                return true;
            }
            return base.CanConvertTo(context, destinationType);
        }

        /// <summary>
        /// 有Object参数和Type参数,将Object转换成Type类型的Object,返回Type类型的Object.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="culture"></param>
        /// <param name="value"></param>
        /// <param name="destinationType"></param>
        /// <returns></returns>
        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            if (destinationType == typeof(System.String) &&
                 value is SpellingOptions)
            {

                SpellingOptions so = (SpellingOptions)value;

                //返回字符串,显示选择结果
                return "校验1:" + so.IsOne +
                       ",校验2: " + so.IsTwo +
                       ",校验3: " + so.IsThree;
            }
            return base.ConvertTo(context, culture, value, destinationType);
        }

        /// <summary>
        /// 返回此转换器是否可以将一种类型的对象转换为此转换器的类型。例如string类型,如果是,返回true,否则返回false;
        /// </summary>
        /// <param name="context">提供格式上下文</param>
        /// <param name="sourceType">表示要转换的类型</param>
        /// <returns></returns>
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            if (sourceType==typeof(string))
            {
                return true;
            }
            return base.CanConvertFrom(context, sourceType);
        }         
    }

具体效果如下:
在这里插入图片描述

下拉复选框

需创建一个新的组件,命名为CheckBoxEx,继承CheckedListBox类
在这里插入图片描述

        [Editor(typeof(CheckBoxEditor), typeof(System.Drawing.Design.UITypeEditor))]
        [Category("下拉复选")]
        [Description("下拉复选")]
        [Browsable(true)]
        public string SchoolChoose { get; set; }
    public class CheckBoxEditor : UITypeEditor
    {
        private CheckBoxEx check;
        public CheckBoxEditor()
        {
            check = new CheckBoxEx();
            check.BorderStyle = BorderStyle.None;
        }

        /// <summary>
        /// 编辑值
        /// </summary>
        /// <param name="context">可用于获取附加上下文信息的 ITypeDescriptorContext。</param>
        /// <param name="provider">一个 IServiceProvider ,此编辑器可用它来获取服务</param>
        /// <param name="value">要编辑的对象。</param>
        /// <returns>对象的新值。 如果尚未更改对象的值,则它返回的对象应与传递给它的对象相同。</returns>
        public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
        {
            if (context != null && context.Instance != null && provider != null)
            {
                IWindowsFormsEditorService service = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
                if (service != null)
                {
                    List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>();
                    if (check.DataSource == null)
                    {
                        list.Add(new KeyValuePair<string, string>("1", "清华"));
                        list.Add(new KeyValuePair<string, string>("2", "北大"));
                        list.Add(new KeyValuePair<string, string>("3", "人大"));
                        list.Add(new KeyValuePair<string, string>("4", "山大"));
                    }
                    check.DataSource = list;
                    // 在提供此服务的属性网格的值字段下方的下拉区域中显示指定控件。
                    service.DropDownControl(check);
                    return check.GetSelectItemValueText;
                }
            }
            return null;
        }

        /// <summary>
        /// 方法使用的编辑器样式,设置复选下拉框
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
        {
            //显示一个下拉箭头按钮,并在下拉对话框中承载用户界面
            return UITypeEditorEditStyle.DropDown;
        }
    }
    /// <summary>
    /// 自定义复选框控件 继承CheckedListBox,设置复选框格式
    /// </summary>
    public partial class CheckBoxEx : CheckedListBox
    {
        public CheckBoxEx()
        {
            InitializeComponent();
        }

        public CheckBoxEx(IContainer container)
        {
            container.Add(this);

            InitializeComponent();
        }

        public CheckItem Add(string code, string value)
        {
            CheckItem item = new CheckItem(code, value);
            Items.Add(item);
            return item;
        }

        public CheckItem Add(CheckItem item)
        {
            Items.Add(item);
            return item;
        }

        #region 获取选择值

        public string GetSelectItemValueText { get { return string.Join(",", GetSelectItemAll.Select(n => n.Value)); } }
        public string GetSelectItemKeyText { get { return string.Join(",", GetSelectItemAll.Select(n => n.Key)); } }

        public List<KeyValuePair<string, string>> GetSelectItemAll
        {
            get
            {
                List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>();
                for (int i = 0; i < Items.Count; i++)
                {
                    CheckItem item = Items[i] as CheckItem;
                    //返回指示指定项是否选中的值。如果选中该项,则为 true;否则为 false。
                    if (GetItemChecked(i))
                    {
                        list.Add(new KeyValuePair<string, string>(item.Code, item.Value));
                    }
                }
                return list;
            }
        }

        #endregion

        #region 绑定数据源

        private object data;

        public new object DataSource
        {
            get
            {
                return data;
            }
            set
            {
                data = value;
                if (data is IEnumerable<KeyValuePair<string, string>>)
                {
                    foreach (KeyValuePair<string, string> item in (data as IEnumerable<KeyValuePair<string, string>>))
                    {
                        Add(item.Key, item.Value);
                    }
                }
                else if (data is IEnumerable<CheckItem>)
                {
                    foreach (var item in (data as IEnumerable<CheckItem>))
                    {
                        Add(item);
                    }
                }
            }
        }

        #endregion
    }

具体效果如下:
在这里插入图片描述

弹窗

创建想要弹出的窗体
在这里插入图片描述

        [Category("弹窗设置")]
        [Description("弹窗")]
        [Editor(typeof(PopUpEditor), typeof(UITypeEditor))]
        [TypeConverter(typeof(PopUpConverter))]
        public string PopUp { get; set; } 
    public class PopUpEditor : UITypeEditor
    {
        private PopUpForm popUpForm;

        /// <summary>
        /// 设置编辑器样式
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
        {
            return UITypeEditorEditStyle.Modal;
        }

        /// <summary>
        /// 编辑指定对象的值
        /// </summary>
        /// <param name="context"></param>
        /// <param name="provider"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
        {
            this.popUpForm = new PopUpForm();
            IWindowsFormsEditorService conService = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
            conService.ShowDialog(this.popUpForm);
            return value;
        }
    }
    public class PopUpConverter : TypeConverter
    {
        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            return true;
        }

        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            if (destinationType == typeof(string))
            {
                return string.Empty;
            }
            return base.ConvertTo(context, culture, value, destinationType);
        }

        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            return true;
        }
    }

具体效果如下:
在这里插入图片描述
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值