using System;
using System.ComponentModel.Design.Serialization;
using System.ComponentModel;
namespace  test
{ public class TSoInfo
{
 public string Brush;
} public class TConvert
{
[STAThread]
static void Main(string[] args)
{

InstanceDescriptor td = new InstanceDescriptor(null,null,false); TSoInfo t=  new TSoInfo(); TypeConverter   tc= new TypeConverter(); tc.ConvertTo(null, null, t, td.GetType()); } }}/*
 * 
 * 未处理的异常: System.NotSupportedException: “TypeConverter”无法将“test.TSoIn
fo”转换为“System.ComponentModel.Design.Serialization.InstanceDescriptor”。
   at System.ComponentModel.TypeConverter.GetConvertToException(Object value, Ty
pe destinationType)
   at System.ComponentModel.TypeConverter.ConvertTo(ITypeDescriptorContext conte
xt, CultureInfo culture, Object value, Type destinationType)
   at test.TConvert.Main(String[] args) in e:\TNC\cs\Project2\tsoinfo.cs:l
ine 26 * */

解决方案 »

  1.   

    这段code还真有他写的exception,是不是他从实际环境中抽取出来的code,
    来重现bug. 
      

  2.   

    widegoose 你说的对, 我把code简化了来重现bug. -------------------------------
    Info1:    如果我自定义一个控件,它当中的一个复杂属性的类型是自定义类,我现在对这个自定义类定义一个TypeConverter,请问我如何能使这个复杂属性像Font、Size属性一样,在属性窗口中显示一个"+"? 
    ---------------------------------------------------------
    Info2:   
    InstanceDescriptor   可以存储描述对象实例的信息。这些信息可用于创建对象的实例。   
      某些自定义序列化程序使用   InstanceDescriptor   来表示可序列化的对象。TypeDescriptor   的若干方法使用   InstanceDescriptor   来表示或实例化对象。   
        
      InstanceDescriptor   提供以下成员:     
        
      描述此对象的   MemberInfo   属性。     
      由构造函数参数组成的   Arguments   属性,可用于实例化此对象。     
      布尔型   IsComplete   属性,指示对象是否由当前信息完全表示。     
      Invoke   方法,可用于创建所表示对象的实例。 
      

  3.   

    自己继承一个TypeConvert类MyClassConverter
    然后你的要转换的类前用
    [TypeConverter(typeof(MyClassConverter))]
     public class MyClass {
      

  4.   

    这里有现成的例子
    http://chs.gotdotnet.com/QuickStart/aspplus/default.aspx?url=%2fquickstart%2fwinforms%2fdoc%2fWinFormsPrinting.aspx
      

  5.   

    Class1.cs
    using System.ComponentModel;
    using System.ComponentModel.Design.Serialization;
    using Test;namespace test {
    [TypeConverter(typeof(MyClassConverter))]
    public class TSoInfo {
    public string name;
    } public class TConvert {
    private static void Main(string[] args) {
    InstanceDescriptor instanceDescriptor = new InstanceDescriptor(null, null, false); TSoInfo tSoInfo = new TSoInfo(); MyClassConverter  myClassConverter  = new MyClassConverter();
    myClassConverter.ConvertTo(null, null, tSoInfo,instanceDescriptor.GetType() ); } }}
    -----------------------------
    MyClassConverter.csusing System.ComponentModel;
    using System.Globalization;namespace Test {
    public class MyClassConverter : System.ComponentModel.TypeConverter {
    public MyClassConverter() {
    } public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, System.Type destinationType) {
    return base.ConvertTo(context, culture, value, destinationType);
    } public override bool CanConvertTo(ITypeDescriptorContext context, System.Type destinationType) {
    return base.CanConvertTo(context, destinationType);
    } }
    }/*
    Exception 
    A first chance exception of type 'System.NotSupportedException' occurred in system.dllAdditional information: 'MyClassConverter' is unable to convert 'test.TSoInfo' to 'System.ComponentModel.Design.Serialization.InstanceDescriptor'.*/
      

  6.   


    Using IDesigner and CodeDomSerializer to create read-only runtime propertieshttp://www.codeproject.com/cs/miscctrl/RuntimeProperties.asp 
    The RuntimePropertiesSerializer handles the serialization of the the component properties to the generated code. Because we ed any read-only properties that we are managing with the DesignOnly attribute, the default serialization will not attempt to serialize these properties when changes are made to the component properties. We have to handle this code generation. For each read-only property, we generate a call to the InitializeReadonlyProperty call of the RuntimePropertiesBase.We call the base code serializer first and a let it to handle all the the default serialization. The Serialize routine is called multiple times depending on what code was being generated. From what I could figure out, if the current context of the IDesignerSerializationManager is null, then the component creation code is being generated. If the current context is a CodeTypeDeclaration, then the component initialization code is being generated. We want to generate additional initialization code for the properties we are managing. The base serializer doesn't generate the leading comments if it didn't generate any initialization code, so we should put them in if we need to.
      

  7.   

    convert the TSoInfo     to a   InstanceDescriptor object