locked
UITypeEditor for data type "System.Type" ? RRS feed

  • Question

  • Hi there,

    I'm creating a class with the design time support.

    One property of it has type "System.Type".

    I'm looking for something, problably TypeConverter and UITypeEditor

    to let developer edit this property via the designer property grid,

    something like when you edit the data type of a column in datatable.

    Can somebody tell me are there any ready-made attribute for this job?

    Or if I have to make it my own, please show me how.

    Many thanks.

    Wednesday, January 28, 2009 3:23 AM

Answers

  • Hi Panya,

    You have to create you own TypeConvertor, here is a sample for your information:

     public class SomeClass  
        { 
            private Type dataType; 
     
            [TypeConverter(typeof(MyTypeConverter))] 
            public Type DataType 
            { 
                get { return dataType; } 
                set { dataType = value; } 
            } 
        } 
     
        public sealed class MyTypeConverter : TypeConverter 
        { 
            // Fields 
            private static Type[] types = new Type[] {  
                typeof(bool), typeof(byte), typeof(char), typeof(DateTime) 
            }; 
     
            private TypeConverter.StandardValuesCollection values; 
     
            // Methods 
            public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) 
            { 
                return ((sourceType == typeof(string)) || base.CanConvertTo(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 == null) || (value.GetType() != typeof(string))) 
                { 
                    return base.ConvertFrom(context, culture, value); 
                } 
                for (int i = 0; i < types.Length; i++) 
                { 
                    if (types[i].ToString().Equals(value)) 
                    { 
                        return types[i]; 
                    } 
                } 
                return typeof(string); 
            } 
     
            public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture,  
                object value, Type destinationType) 
            { 
                if (destinationType == null
                { 
                    throw new ArgumentNullException("destinationType"); 
                } 
                if (destinationType == typeof(string)) 
                { 
                    if (value == null
                    { 
                        return string.Empty; 
                    } 
                    value.ToString(); 
                } 
                if ((value != null) && (destinationType == typeof(InstanceDescriptor))) 
                { 
                    object obj2 = value; 
                    if (value is string
                    { 
                        for (int i = 0; i < types.Length; i++) 
                        { 
                            if (types[i].ToString().Equals(value)) 
                            { 
                                obj2 = types[i]; 
                            } 
                        } 
                    } 
                    if ((value is Type) || (value is string)) 
                    { 
                        MethodInfo method = typeof(Type).GetMethod("GetType"new Type[] { typeof(string) }); 
                        if (method != null
                        { 
                            return new InstanceDescriptor(method, new object[] { ((Type)obj2).AssemblyQualifiedName }); 
                        } 
                    } 
                } 
                return base.ConvertTo(context, culture, value, destinationType); 
            } 
     
            public override TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) 
            { 
                if (this.values == null
                { 
                    object[] objArray; 
                    if (types != null
                    { 
                        objArray = new object[types.Length]; 
                        Array.Copy(types, objArray, types.Length); 
                    } 
                    else 
                    { 
                        objArray = null
                    } 
                    this.values = new TypeConverter.StandardValuesCollection(objArray); 
                } 
                return this.values; 
            } 
     
            public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) 
            { 
                return true
            } 
     
            public override bool GetStandardValuesSupported(ITypeDescriptorContext context) 
            { 
                return true
            } 
        } 


    Best Regards.



    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    • Marked as answer by Zhi-Xin Ye Tuesday, February 3, 2009 9:07 AM
    Tuesday, February 3, 2009 9:06 AM

All replies

  • You are very much on the wrong track with this.  Editing the properties of a Type instance doesn't make sense.  There is no way that you can tell the .NET framework: "here's my type, do something with it".  Type instances are generated from metadata produced by the compiler.  You have to compile something first.  Correspondingly, the Type class only has read-only properties.  Changing their values is not possible.
    Hans Passant.
    Wednesday, January 28, 2009 5:41 AM
  • I'm not sure you've got my point.

    I'm not editing the "System.Type" instance.

    I'm about to edit the "System.Type" property of one simple object, let's say

    Public Class A

        Public Property DataType As Type

        ... getter, setter...

    End Class

    Just want to make something like the DataColumn.DataType property

    (can select String, Integer, Decimal or whatever type from the list in property grid)

    but I don't know which attribute to decorate on it.

    Thanks.

    Wednesday, January 28, 2009 6:40 AM
  • Right, I didn't get your point.  Use a TypeConverter.
    Hans Passant.
    Wednesday, January 28, 2009 7:08 AM
  • Yes, I'm thinking about the TypeConverter

    But there are numerous of TypeConveter to use.

    Some that I know are EnumConverter, ColorConverter, FontConverter.

    I'd checked this page http://msdn.microsoft.com/en-us/library/system.componentmodel.typeconverter.aspx

    (and this http://msdn.microsoft.com/en-us/library/system.drawing.design.uitypeeditor.aspx)

    But still don't find any satisfying one.

    Or we just use the TypeConverter like this?

    <TypeConverter()> Public Property DataType as Type

    or

    <TypeConverter(GetType(TypeConverter))> Public Property DataType as Type

    I don't think so. I'd tried it, though, but still didn't work.

     

    P.S. Example in C# is fine to me

    Wednesday, January 28, 2009 8:46 AM
  • Hi Panya,

    You have to create you own TypeConvertor, here is a sample for your information:

     public class SomeClass  
        { 
            private Type dataType; 
     
            [TypeConverter(typeof(MyTypeConverter))] 
            public Type DataType 
            { 
                get { return dataType; } 
                set { dataType = value; } 
            } 
        } 
     
        public sealed class MyTypeConverter : TypeConverter 
        { 
            // Fields 
            private static Type[] types = new Type[] {  
                typeof(bool), typeof(byte), typeof(char), typeof(DateTime) 
            }; 
     
            private TypeConverter.StandardValuesCollection values; 
     
            // Methods 
            public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) 
            { 
                return ((sourceType == typeof(string)) || base.CanConvertTo(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 == null) || (value.GetType() != typeof(string))) 
                { 
                    return base.ConvertFrom(context, culture, value); 
                } 
                for (int i = 0; i < types.Length; i++) 
                { 
                    if (types[i].ToString().Equals(value)) 
                    { 
                        return types[i]; 
                    } 
                } 
                return typeof(string); 
            } 
     
            public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture,  
                object value, Type destinationType) 
            { 
                if (destinationType == null
                { 
                    throw new ArgumentNullException("destinationType"); 
                } 
                if (destinationType == typeof(string)) 
                { 
                    if (value == null
                    { 
                        return string.Empty; 
                    } 
                    value.ToString(); 
                } 
                if ((value != null) && (destinationType == typeof(InstanceDescriptor))) 
                { 
                    object obj2 = value; 
                    if (value is string
                    { 
                        for (int i = 0; i < types.Length; i++) 
                        { 
                            if (types[i].ToString().Equals(value)) 
                            { 
                                obj2 = types[i]; 
                            } 
                        } 
                    } 
                    if ((value is Type) || (value is string)) 
                    { 
                        MethodInfo method = typeof(Type).GetMethod("GetType"new Type[] { typeof(string) }); 
                        if (method != null
                        { 
                            return new InstanceDescriptor(method, new object[] { ((Type)obj2).AssemblyQualifiedName }); 
                        } 
                    } 
                } 
                return base.ConvertTo(context, culture, value, destinationType); 
            } 
     
            public override TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) 
            { 
                if (this.values == null
                { 
                    object[] objArray; 
                    if (types != null
                    { 
                        objArray = new object[types.Length]; 
                        Array.Copy(types, objArray, types.Length); 
                    } 
                    else 
                    { 
                        objArray = null
                    } 
                    this.values = new TypeConverter.StandardValuesCollection(objArray); 
                } 
                return this.values; 
            } 
     
            public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) 
            { 
                return true
            } 
     
            public override bool GetStandardValuesSupported(ITypeDescriptorContext context) 
            { 
                return true
            } 
        } 


    Best Regards.



    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    • Marked as answer by Zhi-Xin Ye Tuesday, February 3, 2009 9:07 AM
    Tuesday, February 3, 2009 9:06 AM