用户控件中复杂属性的设计时支持

引入

  在设计用户控件的时候(不管是winform还是webform),对于一般的简单属性(string,int,bool……基元类型)系统会为我们自动提供相应的类型转换。举个例子:我们在用户控件中定义一个Age属性,

        public int Age
        {
            get;
            set;
        }

这时我们打开设计器,就会看到

2010-11-18_200106

这个属性了。我们可以随便为其设置int类型的值。但是当我们试着填写一个string类型的字符时,系统就会弹出一个“属性无效”窗口,在这个过程中我们就可以看出系统已经为Age做了类型转换,而且这个转换失败了,因为类型不匹配。

     现在让我们再写一个复杂点的属性Person。先创建一个Person类,它里面包含了name和age属性:

    public class Person
    {
        private string strName;
        private int intAge;

        public string StrName
        {
            get { return strName; }
            set { strName = value; }
        }

        public int IntAge
        {
            get { return intAge; }
            set { intAge = value; }
        }
    }

然后在用户控件中,我们新建一个person的属性:

        private Person person;

        public Person Person
        {
            get { return person; }
            set { person = value; }
        }

打开设计器窗体后我们可以看到Person属性是灰色的

2010-11-18_201553 

为什么会这样呢?答案很简单,系统不知道如何去显示这个属性。但总得显示点儿什么吧?于是无可奈何下显示了person类的类型名。这与我们所期望的形如Location样式的可差远了

2010-11-18_202006

到底差在哪里呢?类型转换器!当我们在Person里面填写"zhangsan,21"的时候,类型转换器就能自动将这两个属性值对应到strName,intAge上面去,这就是类型转换器的作用。那么下面我们就来实现一个person的类型转换器。

实现类型转换器

       首先新建一个新类PersonConverter,用于提供person类型转换的能力,所有的注释我都写在代码里面了,大家一看就明白:

代码

然后在用户控件的person属性上加上这么一句,指定了person的转换器:

        [TypeConverter(typeof(PersonConverter))]
        public Person Person
        {
            get;
            set;
        }

我们现在再来看看person的设计时的样子,这样就和我们需求的一样了。

2010-11-18_205722

这里再教大家一个偷懒的方法,就是实现转换器的时候不必重写最上面的那四个方法,直接重写“提供子属性单独设置的能力”的两个方法就是了。只不过这样person属性显示的效果如下:

2010-11-18_210443

就是person显示的内容变了,子属性还是提供设置。对于要求不高的属性也够了。

实现模态属性编辑器

      前面我们实现了形如Location属性的设计时属性设置支持,但我们有时需要的可能不只是这么复杂的属性设置。比如BackgroundImage这个属性,当我们设置它的时候,系统会弹出一个界面出来让我们选择图片:

2010-11-18_211529

使用这种方式无疑增加了我们选择图片的方便度。那这种形式的设置该如何实现呢?

     首先我们新建一个窗体,这个窗体就是将来需要显示给用户设置属性的(比如上图的“选择资源”窗体)。我们还是以person类为例:

2010-11-18_212737

该窗体的后台代码如下:

代码

这里要注意的一点就是confirm按钮的DialogResult要设置为DialogResult.OK,cancel按钮的DialogResult要设置为DialogResult.Cancel。至于为什么要这么做大家往后看就知道了。

      然后我们再建立一个class PersonModalEditor:System.Drawing.Design.UITypeEditor类,其代码如下:

代码

最后我们在用户控件的person属性上加上这个一句话:

        [Editor(typeof(CategoryModalEditor), typeof(UITypeEditor))]
        public Person Person
        {
            get { return person; }
            set { person = value; }
        }

这句话指定了系统如何打开person的属性编辑器。我们看看效果图:

 2010-11-18_214343

用户按了confirm以后,strName和intAge属性的值就会被成功设置了。

 

原文地址:https://www.cnblogs.com/qianlifeng/p/1881238.html