Monday, 25 June 2012

Cómo controlar el orden de propiedades o categorías en un PropertyGrid

El control PropertyGrid es fantástico para crear herramientas de prototipado rápido, donde podamos cambiar propiedades de objetos de forma rápida y visual. Como ya sabrás, el espacio de nombres System.ComponentModel contiene multitud de atributos y herramientas para personalizar el modo en que las propiedades se agrupan y configuran dentro de un PropertyGrid.

De forma automática, las propiedades se ordenan alfabéticamente según su DisplayName, o se agrupan por categorías (y se aplica el mismo criterio alfabético dentro de éstas) si así lo selecciona el usuario. Lamentablemente, no existe una forma sencilla de poder controlar manualmente el orden de las propiedades o de las categorías.

Existen muchas formas distintas de lograrlo, pero casi todas implican escribir código. Un workaround sencillo, efectivo, y que no implica utilizar código adicional es el siguiente:

1.- Dentro del atributo DisplayName de cada propiedad, o dentro del nombre de cada categoría (atributo Category),  añadiremos por delante tantos caracteres especiales de tipo \u200B como posiciones queramos “subir” dicha propiedad o categoría hacia arriba. Dicho carácter identifica un espacio vacío de longitud 0, por lo que en la práctica no modificará el texto que se muestra en la propiedad, pero sí afectará al algoritmo de ordenación.

En el siguiente ejemplo, se muestra un objeto con dos propiedades Width y Height. De forma natural (por orden alfabético), Height aparecería antes que Width. Para modificar ese comportamiento y lograr el orden inverso, mucho más natural, solo tendremos que modificar los atributos como sigue:

        [Category("Layout")]
        [DisplayName("\u200B\u200BWidth")]
        public float Width
        {
            get { return mWidth; }
            set { mWidth = value; }
        }
        [Category("Layout")]
        [DisplayName("\u200BHeight")]
        public float Height
        {
            get { return mHeight; }
            set { mHeight = value; }
        }

Así, logramos un PropertyGrid correctamente ordenado, como el de la siguiente ilustración:

image

2.- Debemos asegurarnos de que el PropertyGrid utiliza una fuente que soporte dicho carácter, ya que no todas lo hacen. Por ejemplo, la fuente por defecto Microsoft Sans Serif 8.25 lo soporta perfectamente. No obstante, si queréis aseguraros de forma programática de que la fuente es correcta, podéis utilizar este código:

        public UIEditor()
        {
            InitializeComponent();

            this.propertyGrid1.Font = new Font("Microsoft Sans Serif", 8.25f, FontStyle.Regular);
        }