Search code examples
c#propertiesxnapropertygrid

PropertyGrid handling unknown types / custom properties


I've just tried using the PropertyGrid for my "Game Editor" so to edit Objects and such easier, but how do you handle unknown types?

For instance I use XNA and Texture2D is a type of the XNA Framework (others work well, such as Point/Vector) but Texture2D is just a bitmap at it's core, so is there a way to "handle" unknown types and customize how the PropertyGrid can show them?


Solution

  • You can use TypeConverters

    There are generic type converters that inherit from TypeConverter and provide basic behaviours, one of the most useful is ExpandableObjectConverter, that you can use to expand class instances.

        [TypeConverter( typeof( ExpandableObjectConverter ) )]
        public PhysicsObject Physics { get; private set; }
    

    This is an example of my Point3 structure and its custom type converter:

    namespace Microsoft.Xna.Framework
    {
    #if WINDOWS
        public class Point3Converter: System.ComponentModel.ExpandableObjectConverter
        {
            public override bool CanConvertFrom( System.ComponentModel.ITypeDescriptorContext context, Type sourceType )
            {
                return sourceType == typeof( string );
            }
    
            public override object ConvertFrom( System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value )
            {
                try
                {
                    string[] tokens = (( string ) value).Split( ';' );
                    return new Point3( int.Parse( tokens[0] ), int.Parse( tokens[1] ), int.Parse( tokens[2] ) );
                }
                catch
                {
                    return context.PropertyDescriptor.GetValue( context.Instance );
                }
            }
    
            public override object ConvertTo( System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType )
            {
                Point3 p = ( Point3 ) value;
                return p.X +";"+ p.Y+";" + p.Z;
            }
        }
    
        [System.ComponentModel.TypeConverter( typeof( Point3Converter ) )]
    #endif
        public struct Point3
        {
            public int X,Y,Z;
    
            public static readonly Point3 UnitX = new Point3( 1, 0, 0 );
            public static readonly Point3 UnitY = new Point3( 0, 1, 0 );
            public static readonly Point3 UnitZ = new Point3( 0, 0, 1 );
    
            public Point3( int X, int Y, int Z )
            {
                this.X = X;
                this.Y = Y;
                this.Z = Z;
            }
    
            public static Vector3 operator +( Point3 A, Vector3 B )
            {
                return new Vector3( A.X + B.X, A.Y + B.Y, A.Z + B.Z );
            }
    
            public static Point3 operator +( Point3 A, Point3 B )
            {
                return new Point3( A.X + B.X, A.Y + B.Y, A.Z + B.Z );
            }
    
            public static Point3 operator -( Point3 A, Point3 B )
            {
                return new Point3( A.X - B.X, A.Y - B.Y, A.Z - B.Z );
            }
    
            public static Point3 operator -( Point3 A )
            {
                return new Point3( -A.X, -A.Y, -A.Z );
            }
    
    
            public override string ToString( )
            {
                return X+";"+Y+";"+Z;
            }
        }  
    }