Ir al contenido principal

[Silverlight] ComboBox con datos de un enumerado

Hola a todos.

Hoy vamos a ver como hacer un binding en un ComboBox con los valores de un enumerado.
La idea es que usamos el combo con valores de texto, pero después tenemos que convertir al enumerado correspondiente.

Primero vamos a crear una función para convertir el enumerado en un array de elementos Enum.


public Enum[] EnumToArray(Enum enumeration)

    //get the enumeration type

    Type et = enumeration.GetType();
    //get the public static fields (members of the enum)

    System.Reflection.FieldInfo[] fi = et.GetFields(BindingFlags.Static | BindingFlags.Public);
    //create a new enum array

    Enum[] values = new Enum[fi.Length];
    //populate with the values

    for (int iEnum = 0; iEnum < fi.Length; iEnum++)
    {

        values[iEnum] = (Enum)fi[iEnum].GetValue(enumeration);
    }

    //return the array

    return values;
}


Luego vamos a crear un enumerado sencillo... Type1, Type2 y Type3 que es el que vamos a utilizar para rellenar el combo box.
Para ello vamos a crear una función en MainPage.xaml.cs invocando a esta función y usando un bucle foreach rellenamos el combo Box.


private void PopulateListBox()
{
      Enum2ListViewViewModel viewModel = DataContext as Enum2ListViewViewModel;
      if (viewModel != null)
      {
            Enum[] enumValues = viewModel.EnumToArray(new Enum2ListViewViewModel.MyType());
            myListEnum.Items.Clear();
            foreach(Enum enums in enumValues)
            {
                  myListEnum.Items.Add(enums.ToString());
                  // Note that the combo has strings values
                  // however, we going to update a Enum value
            }
      }
}


Como dice el comentario, en el combo vamos a poner string, pero vamos a bindearlo contra un enumeado. ¿Donde está la magia?
Pues la magia está en las funciones Converter.

Creamos una clase para convertir el valor, heredando de IValueConverter.


namespace KurroSoftware.Enum2ListView.Converters
{
    public class MyTypeEnumToStringConverter: IValueConverter
    {

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return value.ToString();
        }


        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return (Enum2ListViewViewModel.MyType)Enum.Parse(typeof(Enum2ListViewViewModel.MyType), value.ToString(), true);
        }
    }
}

Como veras, usamos el Enum.Parse para convertir el string en el enumerado del tipo MyType.

Luego en el XAML, hacemos el binding del combo de la siguiente forma


    <ComboBox x:Name="myListEnum"
              Grid.Column="0"
              Grid.Row="0"
              HorizontalAlignment="Stretch"
              VerticalAlignment="Stretch" 
              SelectedValue="{Binding TypeEnum, Converter={StaticResource MyTypeEnum}, Mode=TwoWay}" 
              Grid.ColumnSpan="2" />


Como verás, esta accediendo directamente a la property TypeEnum que es del tipo MyEnum, pero usando el Converter, se hace la traducción string-enum.


    xmlns:converter="clr-namespace:KurroSoftware.Enum2ListView.Converters"
    ......


    <UserControl.Resources>
        <converter:MyTypeEnumToStringConverter x:Key="MyTypeEnum" />
    </UserControl.Resources>


Usando este pequeño truco, podemos hacer un binding directamente con el content.

Para rizar el rizo, y como estoy acostumbrado a la metodología de MVVM (Model-View-ViewModel), he usado la clase CommandDelegate para que la lógica del botón que está en la vista, esté siendo ejecutada en el ViewModel, en lugar del View.
Esto es sencillo usando el patrón Prism (ver http://msdn.microsoft.com/es-es/magazine/dd943055.aspx ), pero por no tener que usar todas las librerías de este patrón, he usado el CommandDelegate que publicó Kunal Chowdhury en CodeProject, (ver Step by Step Guide to Silverlight 4 Command Binding )

Bueno, pues ya sabes, el código en el siguiente enlace.
Enum2ComboBox.zip

Espero tus comentarios.

Comentarios

Publicar un comentario

Si quieres comentar, criticar, aportar mas informacion o simplemente felicitar, inserta tu comentario a continuacion. Entre todos podemos hacer cosas grandes.

Entradas populares de este blog

[PB] - Convertir Numero en Letra

¿Alguna vez has necesitado crear un proceso que tenga que traducir números a letras? Por ejemplo, para un proceso de emisión de cheques. Pues esta es la rutina que necesitas En este caso, vamos a desarrollar un traductor en dos idiomas, es castellano y en catalán. Para ello vamos a usar la función GlobalReplace que viene con las PFC's, pero si no las usas, no importa porque la he extraído para este ejemplo. 1- Creamos un objeto de usuario no visual autoinstanciable, por ejemplo lo llamamos ncst_num2txt 2- Definimos las siguientes variables de instancia private String is_cifra[],is_centenas[] 3- Creamos las funciones de of_GloblalReplace y otra para sobrecargar por defecto la opción de IgnoreCase (Esto lo puedes encontrar en la PFCs) public function string of_GlobalReplace (string as_Source, string as_Old, string as_New, boolean ab_IgnoreCase); ////////////////////////////////////////////////////////////////////////////// // // Function:   of_GlobalRe...

[PB] Crear barra de botones de forma dinámica

Hola de nuevo... hoy, Power Builder, esta vez en PB 10.5 La idea de tener una barra de botones de forma dinámica me hizo idear el siguiente código. Podemos crear un objeto de forma dinámica directamente en nuestra window usando el comando OpenUserOject. this.OpenUserObject(uo_boton) Esta instrucción en la ventana, pondrá un objeto de usuario llamado uo_boton en la ventana, luego podemos invocar las propiedades para poner el botón en el sitio que queremos (X=23, Y=24, etc..) Pero el problema era que lo que tenia era un objeto de usuario y quería poner esos botones dentro del objeto de usuario... grave problema. La solución la dio nuestro amigo Microsoft, porque nos facilita las cosas usando los manejadores de los objetos. Function ulong SetParent (ulong hWndChild, ulong hWndNewParent) Library "USER32.DLL" Esta API cambia el manejador padre de un objeto dado, es decir, si tengo el Handle del objeto de usuario y el Handle del boton, puedo deci...