Thursday, 2 October 2008

Making a PropertyGrid´s property expandable, in one second

The PropertyGrid control is one of the most useful controls in the .Net framework. As you probably know, it uses reflection to guess all the public properties of an object, showing them in a user-friendly interface where you can see and change property values.




The wonderful thing about this control is that it automatically creates the user interface and behaves correctly for ReadOnly properties, multiple object selections, anykind of datatype, specific user interfaces for data types (like combos, ColorPickers, DateTimePicker), etc... The list of features is almost endless.

Someone asked me today how to take advantage of another of it´s features: Expandable Properties.

If you don´t know exactly what I´m talking about, let me introduce it with the following example:

public class Car

{

...

private int mLength;

public int Length

{

get{return mLength;}

set{mLength = value;}

}


private Environment mEnv;

public Environment Env

{

get{return mEnv;}

set{mEnv = value;}

}

...

}


And now, somewhere else you use that class, putting it into a PropertyGrid, so you can inspect and change it´s contents:


Car mCar = new Car();

this.propertyGrid1.SelectedObject = mCar;


The property grid will behave correctly for the "Length" property, allowing you to change it´s value and detecting if the value entered is an "int". BUT, what happens with the "Env" property? It is not a basic DataType. It´s not a default complex type of the FrameWork.

By default, the PropertyGrid will only show the string description of the object Env (the return value of the ToSring() method, which can be overriden), making it read only. If only we could make the PropertyGrid treat that object as an expandable property, allowing us to see it´s internals...

Easy as shit! Add this to the definition of the property:


[TypeConverter(typeof(ExpandableObjectConverter))]

public Environment Env
{
get{return mEnv;}
set{mEnv = value;}
}


This way, you tell the PropertyGrid it should treat that object that way, and it will add at it´s left a Plus/Minus sign allowing you to expand the object. Easy, isn´t it?

Note: You have to include a "#using System.ComponentModel" to make this work.


BMW Z4 Roadster. The beauty, not the beast

Ayer, tuve otra gran oportunidad de deleite automovilístico. De la mano de este chiquitín:


BMW Z4 Roadster 3.0i

Lástima que solo tuve diez minutillos para darme una vuelta de unos pocos km.

Es nervioso, el cabroncete, máxime si pulsas el "boton de la risa". Me pareció que tiene una dirección muy muy directa, incluso más que la del Porsche Boxster S (adelantando a un ciudadano, y tras un "suave" toque de volante, por poco salto de golpe del carril 1 al carril 3... Madre mía...).

El motor me pareció un poco perezoso hasta bien entradas las 5000 rpm. A partir de ahí empuja con ganas. También suena muy muy bien, no es un Porsche, pero no está nada mal. Es un sonido más refinado, un poco más suave, como si el Z4 fuera el "dandy", y el porsche fuera el "grasiento" macarra.



Los materiales del interior, muy buenos. Como debe ser. Una cosa que me gustó es que la apertura de la capota es totalmente eléctrica. En ningún momento requiere de cooperación alguna por parte del conductor, algo que sí es necesario en el Porsche.



Otra cosa en que aventaja al de Stuttgart es en capacidad del maletero. Para ser un deportivo biplaza, y además roadster, tiene un maletero más que aceptable (eso sí, solo uno). No se donde meten la lona cuando se recoge...


La posición de conducción me pareció mejor en el Porsche, aunque tengo que reconocer que no tuve tiempo para ajustar asiento y volante a mi gusto. No obstante, este coche también pasa la prueba del orangután.



En fin, algún dia... snifff...