jueves, 23 de diciembre de 2010

Usar bindings de XAML para mostrar valores de tipos enumerados en controles WPF

Microsoft.NET

Este artículo es breve y consiste en una respuesta a  un pequeño tutorial que publicó mi amigo Feston en  su blog. Su solución consiste en utilizar el método GetValues para obtener un arreglo con todos los valores definidos para el tipo de datos en cuestión. Sin embargo, ¿realmente es necesario escribir líneas de código para lograr esto? Continúe leyendo y conocerá una alternativa que logra el mismo efecto, pero sólo utiliza el fichero XAML (que es dónde debería especificarse este tipo de cosas).

El procedimiento es simple (qué otra cosa podría decir :). Comencemos por crear una aplicación WPF sencilla (menú File > New > Project ... y selccionar WPF Application). El Visual Studio mostrará el editor WPF con una ventana vacía. Para hacer más simple el ejemplo, editaré el fichero Window1.xaml.cs para que luzca de la forma siguiente. Esto no implica que haya pérdida de generalidad en la discusión, puesto a que los pasos son similares si el tipo enumerado se define en otro fichero o assembly.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace EnumNamespace {
    public enum MyEnum {Value1, Value2, Value3, Value4}
}

namespace WpfEnumBinding {
    public partial class Window1 : Window {
        public Window1() {
            InitializeComponent();
        }
    }
}

Una vez hecho esto, se añade en el fichero XAML una referencia al namespace dónde se encuentra el tipo enumerado y otra al namespace System (seguro que el IntelliSense ayudará mucísimo ;o). Luego se define un recurso del tipo ObjectDataProvider que permita hacerle binding al valor que devuelve el método GetValues. Posteriormente se utiliza la extension StaticResource para hacer referencia al valor en cuestión. Si utilizamos un combobox, el fichero XAML queda de la siguiente manera:

<Window x:Class="WpfEnumBinding.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:EnumNamespace="clr-namespace:EnumNamespace"
    xmlns:System="clr-namespace:System;assembly=mscorlib"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <ObjectDataProvider x:Key="MyEnumResource" 
                            MethodName="GetValues" 
                            ObjectType="{x:Type System:Enum}">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="EnumNamespace:MyEnum" />
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="25" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <ComboBox ItemsSource="{Binding Source={StaticResource MyEnumResource}}"/>
    </Grid>
</Window>

... y la aplicación luce así

Espero que les sea útil esta sugerencia, al menos para aplicar en otras circunstancias parecidas los conocimientos adquiridos. Si le gustó este artículo le digo que los demás serán igual de interesantes, por lo que le invito a  suscribirse a este blog para que este al tanto de otros trucos similares. No lo olvide simelo pide siempre habrá una respuesta a esa inquietud o duda que Usted tenga del mundo de la informática y la programación.

Moropo: Bind de un tipo Enum a un combobox en C#

1 comentario:

  1. De acuerdo, pero la mayoría de las veces los valores de un enum no están hechos para ser visualizados, por ejemplo, SpecialValue.

    En tal caso, un value converter es recomendable (se puede hacer algo generico que separe las palabras Special y Value, por ejemplo)

    Buen blog!

    ResponderEliminar