Haciendo Bindings de Enumeraciones en WPF

Una pregunta muy recurrente cuando explico el Binding es como hacer Binding de Enums a un ComboBox, en este post voy a explicarlo mediante un ejemplo, imaginemos que tenemos la enumeración

 public enum Deporte
    {
        Futbol,
        Baloncesto,
        Atletismo,
        Balonmano,
        Golf
    }

Donde indicamos el tipo de deporte que practicamos, aquí tenéis la clase Persona

public class Persona : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }

        private string _nombre;
        public string Nombre
        {
            get
            {
                return _nombre;
            }
            set
            {
                if (value != _nombre)
                {
                    _nombre = value;
                    NotifyPropertyChanged("Nombre");
                }
            }
        }

        private string _apellido1;
        public string Apellido1
        {
            get
            {
                return _apellido1;
            }
            set
            {
                if (value != _apellido1)
                {
                    _apellido1 = value;
                    NotifyPropertyChanged("Apellido1");
                }
            }
        }

        private string _apellido2;
        public string Apellido2
        {
            get
            {
                return _apellido2;
            }
            set
            {
                if (value != _apellido2)
                {
                    _apellido2 = value;
                    NotifyPropertyChanged("Apellido2");
                }
            }
        }

        private Deporte _practico;
        public Deporte Practico
        {
            get
            {
                return _practico;
            }
            set
            {
                if (value != _practico)
                {
                    _practico = value;
                    NotifyPropertyChanged("Practico");
                }
            }
        }

    }

Ahora creamos la carga de una ObservableCollection<Persona> al DataContext

void Window1_Loaded(object sender, RoutedEventArgs e)
        {
            DataContext = new ObservableCollection<Persona>()
                              {
                                  new Persona("Oscar", "Alvarez", "Guerras", Deporte.Atletismo),
                                  new Persona("Jose", "Rodriguez", "Fernandez", Deporte.Futbol),
                                  new Persona("Jorge", "Elorza", "Blanco", Deporte.Baloncesto),
                                  new Persona("Noelia", "Gomez", "Souto", Deporte.Futbol)
                              };
        }

Ahora tenemos dos maneras de enlazar la enumeración por código

PracticaComboBox.ItemsSource = Enum.GetValues(typeof(Deporte));

o usando solo XAML

 

<ObjectDataProvider MethodName="GetValues" ObjectType="{x:Type sys:Enum}" x:Key="sysEnum">
 	<ObjectDataProvider.MethodParameters> 
	    <x:Type TypeName="local:Deporte" />
         	</ObjectDataProvider.MethodParameters> 
</ObjectDataProvider> 

Creamos on ObjectDataProvider para el tipo Deporte con el nombre sysEnum, demanera que para enlazarlo con el combo nos quedaría

<ComboBox ItemsSource="{Binding Source={StaticResource sysEnum}}" SelectedValue="{Binding Practico}"  Width="195" />

Si juntamos todo el Xaml de la ventana nos podría quedar

 

<Window x:Class="WPFtestEnumBindings.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WPFtestEnumBindings"
    xmlns:System="clr-namespace:System;assembly=mscorlib"
    Title="Window1" Height="500" Width="500">
    <Window.Resources>
        <ObjectDataProvider MethodName="GetValues" ObjectType="{x:Type System:Enum}" x:Key="sysEnum">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="local:Deporte" />
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>

    </Window.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="132*" />
            <ColumnDefinition Width="146*" />
        </Grid.ColumnDefinitions>
        <ListBox ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True" Grid.Column="0">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Margin="0,0,0,10">
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="{Binding Nombre}" Margin="0,0,5,0" />
                            <TextBlock Text="{Binding Apellido1}" Margin="0,0,5,0"/>
                            <TextBlock Text="{Binding Apellido2}" />
                        </StackPanel>
                        <TextBlock Text="{Binding Practico}" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <StackPanel Grid.Column="1">
            <StackPanel Orientation="Horizontal">
                <Label Content="Nombre: " />
                <TextBox Text="{Binding Nombre}"  Width="186" />
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <Label Content="Apellido 1: " />
                <TextBox Text="{Binding Apellido1}"  Width="177" />
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <Label Content="Apellido 2: " />
                <TextBox Text="{Binding Apellido2}" Width="175" />
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <Label Content="Practica: " />
                <ComboBox ItemsSource="{Binding Source={StaticResource sysEnum}}" SelectedValue="{Binding Practico}"  Width="195" />
            </StackPanel>
        </StackPanel>

    </Grid>
</Window>

 

El cs sería

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
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 WPFtestEnumBindings
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            Loaded += new RoutedEventHandler(Window1_Loaded);
        }

        void Window1_Loaded(object sender, RoutedEventArgs e)
        {
            DataContext = new ObservableCollection<Persona>()
                              {
                                  new Persona("Oscar", "Alvarez", "Guerras", Deporte.Atletismo),
                                  new Persona("Jose", "Rodriguez", "Fernandez", Deporte.Futbol),
                                  new Persona("Jorge", "Elorza", "Blanco", Deporte.Baloncesto),
                                  new Persona("Noelia", "Gomez", "Souto", Deporte.Futbol)
                              };
        }
    }
}

 

Y nos da como resultado la ventana

 

image

 

Probarlo y a disfrutar…

 

 

 

4 comentarios sobre “Haciendo Bindings de Enumeraciones en WPF”

  1. Hola Oscar, muy buen ejemplo.

    Una duda que tengo es sobre realizar un binding en un control sobre un elemento específico de una colección genérica.
    Por ejmplo, en un objeto de negocio tengo un tipo: EntityList (en donde el tipo EntityList implementa INotifyPropertyChange).
    Y en la UI tengo un control al que quiero bindear al elemento i-ésimo de esta lista. Se te ocurre alguna manera de realizar esto ?

    Gracias de antemano y te felicito por el blog.

    Saludos!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *