How does a Silverlight DataForm automatically create a binding from a ComboBox to an enumeration?

I am trying to understand DataForm as implemented in the November 2009 toolbox, and I cannot figure out how to associate a ComboBox with an enumeration. Does anyone know how DataForm does this automatically?

Background

First, I created a class and Enum, following this article, and allowed the DataForm to generate fields. The DataForm generated a TextBox field for the Name field and (what I assume) for a ComboBox for the enum genres field.

My first goal in understanding how to set up a DataForm is to reproduce what is done in auto-generation. I managed to make TextBoxes (and a DatePicker excluded from this code), but I'm struggling to associate a ComboBox with an enumeration.

Here are the classes (simplified):

public class Movie { public string Name { get; set; } public Genres Genre { get; set; } } public enum Genres { Comedy, Fantasy, Drama, Thriller } 

and then in MainPage I do this:

 private ObservableCollection<Movie> movies = new ObservableCollection<Movie>(); private void UserControl_Loaded(object sender, RoutedEventArgs e) { Movie movie = new Movie() { Name = "Fred", Genre = Genres.Thriller }; movies.Add(movie); myDataForm.ItemsSource = movies; } 

and in MainPage.xaml in the grid:

 <dataFormToolkit:DataForm x:Name="myDataForm" AutoEdit="False" AutoCommit="False" Header="Foo Movie DB"> </dataFormToolkit:DataForm> 

for automatically generated material. When trying to generate it manually, I got:

 <dataFormToolkit:DataForm x:Name="myDataForm" AutoEdit="False" AutoCommit="False" Header="Foo Movie DB"> <StackPanel Orientation="Vertical"> <dataFormToolkit:DataField> <TextBox Text="{Binding Name, Mode=TwoWay}"/> </dataFormToolkit:DataField> <dataFormToolkit:DataField> <ComboBox ItemsSource="{Binding Genres}" SelectedItem="{Binding Genre, Mode=TwoWay}" /> </dataFormToolkit:DataField> </StackPanel> </dataFormToolkit:DataForm> 

but ComboBox is not working. There are many articles covering this, but it seems that much of what they offer is too much for an automatic generator (for example, for a subclass of ComboBox to provide SelectedValue). Do you know how tools do this for us?

+6
enums data-binding combobox
source share
2 answers

This is the code that executes the DataForm ...

 ComboBox comboBox = new ComboBox(); FieldInfo[] valueFieldInfos = type.GetFields(BindingFlags.Public | BindingFlags.Static); List<string> valueList = new List<string>(); foreach (FieldInfo valueFieldInfo in valueFieldInfos) { Enum value = valueFieldInfo.GetValue(null) as Enum; if (value != 0) { valueList.Add(value.ToString()); } } comboBox.ItemsSource = valueList; return comboBox; 
+4
source share

You can do this with IValueConverter:

XAML:

  <ComboBox Width="100" Height="30" ItemsSource="{Binding GenreSource,Converter={StaticResource ec}}" SelectedItem="{Binding SelectedGenre, Mode=TwoWay, Converter={StaticResource gc}}"></ComboBox> public class DemoViewModel : ViewModel { public DemoViewModel() { } public Type GenreSource { get { return typeof(Genres); } } private Genres _SelectedGenre; public Genres SelectedGenre { get { return _SelectedGenre; } set { _SelectedGenre = value; OnPropertyChanged("SelectedGrape"); } } } 

Convert from Enum to list for ComboBox:

 public class EnumListConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { var enumType = (Type)value; var names = new List<string>(); foreach (var fieldInfo in enumType.GetFields(BindingFlags.Static | BindingFlags.Public)) { names.Add(fieldInfo.Name); } return names; } 

and convert from string back to list:

  public class GenreConverter : 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 (Views.Genres)Enum.Parse(typeof(Views.Genres), value.ToString(), false); } } 

You can pass the fully qualified type name to GenreConverter to make this common to any enumeration

+5
source share

All Articles