自己创建了个类用于收纳控件属性,这个类带有个Image类型的字段,但在使用的时候,字符串等类型数据都能成功记录设计时设置,Image就不可以,该如何解决?代码如下:
    /// <summary>
    /// Banner内容信息类
    /// </summary>
    [TypeConverter(typeof(BannerContentInfoConverter))]
    public sealed class BannerContentInfo
    {
        private string _caption = "标题";
        /// <summary>
        /// 获取或设置Banner标题
        /// </summary>
        [Category("Appearance"), DefaultValue("标题"), Description("设置Banner标题")]
        public string Caption
        {
            get
            {
                return _caption;
            }
            set
            {
                if (value == null)
                {
                    value = "";
                }
                if (value != this._caption)
                {
                    this._caption = value;
                    this.EnsureInvalidate(false);
                }
            }
        }        private string _description = "";
        /// <summary>
        /// 获取或设置Banner说明
        /// </summary>
        [Category("Appearance"), DefaultValue(""), Description("设置Banner说明")]
        public string Description
        {
            get
            {
                return _description;
            }
            set
            {
                if (value == null)
                {
                    value = "";
                }
                if (value != this._description)
                {
                    _description = value;
                    this.EnsureInvalidate(false);
                }
            }
        }        private Image _glyph = null;
        /// <summary>
        /// 获取或设置Banner图标
        /// </summary>
        [Category("Appearance"), DefaultValue((string)null), Description("设置Banner图标")]
        public Image Glyph
        {
            get
            {
                return this._glyph;
            }
            set
            {
                if (_glyph != null)
                {
                    this._glyph = value;
                    this.EnsureInvalidate(false);
                }
            }
        }        /// <summary>
        /// 获取Banner内容的文字形式
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return string.Format(CultureInfo.CurrentCulture, "[{0}: Caption={1}, Description={2}, Units={3}, GdiCharSet={4}, GdiVerticalFont={5}]", new object[] { base.GetType().Name, this.Caption, this.Description});//, (int)this.fontUnit, this.gdiCharSet, this.gdiVerticalFont });
        }
    }

解决方案 »

  1.   

    下面的是 类型转换器代码:    internal class BannerContentInfoConverter : TypeConverter
        {
            private const string DataHdr = "data=";        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
            {
                return ((sourceType == typeof(string)) || base.CanConvertFrom(context, sourceType));
            }        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
            {
                return ((destinationType == typeof(InstanceDescriptor)) || base.CanConvertTo(context, destinationType));
            }        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
            {
                if (value is string)
                {
                    string text = (value as string).Trim();
                    if (text.Length == 0)
                    {
                        return new BannerContentInfo();
                    }
                    if (culture == null)
                    {
                        culture = CultureInfo.CurrentCulture;
                    }
                    string separator = culture.TextInfo.ListSeparator + " " + DataHdr;
                    string[] datas = text.Split(new string[] { separator }, StringSplitOptions.None);
                    if (datas.Length < 2 || datas.Length > 3)
                    {
                        throw new ArgumentException("1|" + separator + "|" + value.ToString());
                    }
                    string caption = datas[0];
                    string description = datas[1];
                    Image glyph = null;
                    if(datas.Length == 3)
                    {
                        try
                        {
                            byte[] glyphData = Convert.FromBase64String(datas[2]);
                            TypeConverter convert = TypeDescriptor.GetConverter(typeof(Image));
                            if (convert != null)
                            {
                                glyph = convert.ConvertFrom(glyphData) as Image;
                            }
                        }
                        catch
                        {
                        }
                    }
                    return new BannerContentInfo() { Caption = caption, Description = description, Glyph = glyph };
                }
                if (value is BannerContentInfo)
                {
                    BannerContentInfo content = value as BannerContentInfo;
                    return new BannerContentInfo() { Caption = content.Caption, Description = content.Description, Glyph = content.Glyph };
                }
                return base.ConvertFrom(context, culture, value);
            }        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
            {
                if (destinationType == null)
                {
                    throw new ArgumentNullException("destinationType");
                }
                if (destinationType == typeof(string))
                {
                    BannerContentInfo content = value as BannerContentInfo;
                    if (content == null)
                    {
                        return "toStringNone";
                    }
                    if (culture == null)
                    {
                        culture = CultureInfo.CurrentCulture;
                    }
                    string separator = culture.TextInfo.ListSeparator + " " + DataHdr;
                    int count = 2;
                    if (content.Glyph != null)
                    {
                        count++;
                    }
                    string[] datas = new string[count];
                    int index = 0;
                    datas[index++] = content.Caption;
                    datas[index++] = content.Description;
                    if (content.Glyph != null)
                    {
                        TypeConverter convert = TypeDescriptor.GetConverter(typeof(Image));
                        byte[] glyph = convert.ConvertTo(content.Glyph, typeof(byte[])) as byte[];
                        datas[index++] = Convert.ToBase64String(glyph);
                    }
                    return string.Join(separator, datas);
                }
                if ((destinationType == typeof(InstanceDescriptor)) && (value is BannerContentInfo))
                {
                    BannerContentInfo content = (BannerContentInfo)value;
                    return new BannerContentInfo() { Caption = content.Caption, Description = content.Description, Glyph = content.Glyph };
                }
                return base.ConvertTo(context, culture, value, destinationType);
            }        public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues)
            {
                if (propertyValues == null)
                {
                    throw new ArgumentNullException("propertyValues");
                }
                string caption = propertyValues["Caption"] as string;
                string description = propertyValues["Description"] as string;
                Image glyph = propertyValues["Glyph"] as Image;
                return new BannerContentInfo() { Caption = caption, Description = description, Glyph = glyph };
            }        public override bool GetCreateInstanceSupported(ITypeDescriptorContext context)
            {
                return true;
            }        public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
            {
                return TypeDescriptor.GetProperties(typeof(BannerContentInfo), attributes).Sort(new string[] { "Caption", "Description", "Glyph" });
            }        public override bool GetPropertiesSupported(ITypeDescriptorContext context)
            {
                return true;
            }
        }
      

  2.   

    1、有错别字的原因:)        [Category("Appearance"), DefaultValue((string)null), Description("设置Banner图标")]
            public Image Glyph
            {
                get
                {
                    return this._glyph;
                }
                set
                {
                    //if (_glyph != null)
                    if( value != null)                      //<------------
                    {
                        this._glyph = value;
                        this.EnsureInvalidate(false);
                    }
                }
            }
      

  3.   

     private Image _glyph = null;
            /// <summary>
            /// 获取或设置Banner图标
            /// </summary>
            [Category("Appearance"), DefaultValue((string)null), Description("设置Banner图标")]
            public Image Glyph
            {
                get
                {
                    return this._glyph;
                }
                set
                {
                    if (_glyph != null)
                    {
                        this._glyph = value;
                        this.EnsureInvalidate(false);
                    }
                }
            }
      

  4.   

    2、我没有看出你的TypeConverter实际起了什么作用,不如不写,而是直接用ExpandableObjectConverter。
    你TypeConverter中转换为InstanceDescriptor的实现有误
        class My : Component
        {
            BannerContentInfo bi = new BannerContentInfo();
            public BannerContentInfo BB { get { return bi; } set { bi = value; } }
        }    [TypeConverter(typeof(ExpandableObjectConverter))]             //<---
        public sealed class BannerContentInfo
        {
           //...
        }
      

  5.   

     使用默认的EXPANDABLEOBJECTCONVERT类后,发现数据不能保存。
      

  6.   

    火了,开始都很好的,突然不能保存数据了,总说不能把 BannerContentInfo 转换为 TypeDescriptor。郁闷。
      

  7.   

    ““BannerContentInfoConverter”无法将“Superdata.WebCAD.Common.UI.UIComponents.BannerContentInfo”转换为“System.ComponentModel.Design.Serialization.InstanceDescriptor”。”
      

  8.   

    通过一天的调试,终于发现,出现这个问题的原因是DLL被重新编译了,此时,IDE使用的类型以及类型转换DLL却跟目标代码使用的类型不一致,这些代码我都是放在一个模块的。假如IDE使用的设计时DLL能自动更新就好了。每次修改都要重新打开VSIDE,还是有点烦。