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
Probarlo y a disfrutar…
Una pregunta muy recurrente cuando explico el Binding es como hacer Binding de Enums a un ComboBox, en
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. (en donde el tipo EntityList implementa INotifyPropertyChange).
Por ejmplo, en un objeto de negocio tengo un tipo: EntityList
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!
Solo tendrias que pasar a la propiedad DataContext de tu control el objrto de la lista que quieres hacer el binding
Hola Felipe, lo puedes hacer perfectamente mediante XAML