c# 自定义控件的集合属性

自定义集合属性

自定义控件中的属性,如果是集合的话,例如List<T>,需要保证T类是可序列化的(注意,C#的控件都是继承与Control的,因此并不能序列化,因为序列化要求父类也是可序列化的),方法很简单,在T类上增加注解[Serializable]

[Serializable]
public class MultiStageItem

如果想要通过窗体的属性设计器来设计集合属性的话,为了使在设计器中的修改生效,必须在集合属性上添加注解[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]

DesignerSerializationVisibility(Design erSerializationVisibility.Visible)指定应该允许序列化程序序列化属性的值;
DesignerSerializationVisibility(DesignerSerializationVisibility.Content)指定序列化程序应该序列化属性的内容,而不是属性本身。此字段为只读,Visible为其默认值。
只有指定了改特性后,点击“集合编辑器”的确定按钮后,VS.studio才能生成相应的添加代码(即对属性进行序列化)。

还要添加编辑器[Editor()]注解
目前我写的集合属性的注解包括以下内容:

private List<MultiStageItem> subAttriList = new List<MultiStageItem>();
[Description("菜单项属性列表"), Category("自定义属性")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content), MergableProperty(false)]
[TypeConverter(typeof(System.ComponentModel.CollectionConverter))]
[Editor(typeof(System.ComponentModel.Design.CollectionEditor), typeof(System.Drawing.Design.UITypeEditor))]
public List<MultiStageItem> SubAttriList
{
            get { return subAttriList; }
            set
            {
                List<MultiStageItem> list = value;
                subAttriList.Clear();
                foreach (MultiStageItem i in list)
                {
                    subAttriList.Add(i);
                }
            }
}

但是有个问题目前还没有解决办法,在修改控件之后再重新编译,设计器会报错:
“不能将MultiStageItem[]转换为MultiStageItem[]类型”,目前我找不到解决办法。遇到这个问题,重启VS之后就会恢复。然后不定时又会出问题。

更新与2017年11月23日

找到了一个解决办法,目前没有出问题。
关键是要对集合属性中的类进行序列化。由于自定义的类中包含Color、Font等没有序列化方法的类,所以需要自定义序列化。

1. 首先实现ISerializable接口

public class MultiStageItem : ISerializable{
}

2. 序列化Color

/// <summary>
        /// 序列化颜色属性,将颜色转成字符串
        /// </summary>
        /// <param name="clr">颜色</param>
        /// <returns>字符串</returns>
        private string serializeColor(Color clr)
        {
            return string.Format("{0}:{1}:{2}:{3}", clr.A, clr.R, clr.G, clr.B);
        }
        /// <summary>
        /// 反序列化颜色属性,从字符串转换成颜色
        /// </summary>
        /// <param name="color">字符串</param>
        /// <returns>颜色</returns>
        private Color deserializeColor(string color)
        {
            string[] pieces = color.Split(':');
            byte a = byte.Parse(pieces[0]),
                r = byte.Parse(pieces[1]),
                g = byte.Parse(pieces[2]),
                b = byte.Parse(pieces[3]);
            return Color.FromArgb(a, r, g, b);
        }

3. 序列化Font

/// <summary>
        /// 用于序列化的字体属性类
        /// </summary>
        [Serializable]
        private struct FontStruct
        {
            public string fontFamily;
            public GraphicsUnit unit;
            public float size;
            public FontStyle style;
            /// <summary>
            /// 将字体转换成属性类
            /// </summary>
            /// <param name="f">字体</param>
            public FontStruct(Font f)
            {
                fontFamily = f.FontFamily.Name;
                unit = f.Unit;
                size = f.Size;
                style = f.Style;
            }
            /// <summary>
            /// 将属性类转成字体
            /// </summary>
            /// <returns>字体</returns>
            public Font toFont()
            {
                return new Font(fontFamily, size, style, unit);
            }
        }

4. 增加整体对象的序列化和反序列化函数

通过构造函数实现反序列化

/// <summary>
        /// 普通构造函数
        /// </summary>
        public MultiStageItem() { }
        /// <summary>
        /// 反序列化的构造函数
        /// </summary>
        /// <param name="info"></param>
        /// <param name="context"></param>
        public MultiStageItem(SerializationInfo info, StreamingContext context)
        {
            Width = info.GetInt32("Width");
            Height = info.GetInt32("Height");
            backColor = deserializeColor(info.GetString("backColor"));
            focusColor = deserializeColor(info.GetString("focusColor"));
            font = ((FontStruct)info.GetValue("font", typeof(FontStruct))).toFont();
            foreColor = deserializeColor(info.GetString("foreColor"));
            leftMargin = info.GetInt32("leftMargin");
            titleText = info.GetString("titleText");
            subList = (List<MultiStageItem>)info.GetValue("subList", typeof(List<MultiStageItem>));
        }

/// <summary>
        /// 将对象序列化
        /// </summary>
        /// <param name="info"></param>
        /// <param name="context"></param>
        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            //throw new NotImplementedException();
            info.AddValue("Width", Width);
            info.AddValue("Height", Height);
            info.AddValue("backColor", serializeColor(backColor));
            info.AddValue("focusColor", serializeColor(focusColor));
            info.AddValue("font", new FontStruct(font));
            info.AddValue("foreColor", serializeColor(foreColor));
            info.AddValue("leftMargin", leftMargin);
            info.AddValue("titleText", titleText);
            info.AddValue("subList", subList);
        }
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容