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

自定义集合属性

自定义控件中的属性,如果是集合的话,例如List,需要保证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 subAttriList = new List();
[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 SubAttriList
{
            get { return subAttriList; }
            set
            {
                List 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

/// 
        /// 序列化颜色属性,将颜色转成字符串
        /// 
        /// 颜色
        /// 字符串
        private string serializeColor(Color clr)
        {
            return string.Format("{0}:{1}:{2}:{3}", clr.A, clr.R, clr.G, clr.B);
        }
        /// 
        /// 反序列化颜色属性,从字符串转换成颜色
        /// 
        /// 字符串
        /// 颜色
        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

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

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

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

/// 
        /// 普通构造函数
        /// 
        public MultiStageItem() { }
        /// 
        /// 反序列化的构造函数
        /// 
        /// 
        /// 
        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)info.GetValue("subList", typeof(List));
        }

/// 
        /// 将对象序列化
        /// 
        /// 
        /// 
        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);
        }

你可能感兴趣的:(c# 自定义控件的集合属性)