I'm trying to understand DataForm as implemented in the November 2009 toolkit and I can't work out how to bind a ComboBox to an enum. Does anyone know how the DataForm does this automatically?
Background
First I created a class and an Enum, following this article and allowed the DataForm to generate the fields. The DataForm generated a TextBox for the Name string field and (what I assume is) a ComboBox for the Genres enum field.
My first aim in understanding how to customize the DataForm is to reproduce what is produced in the auto-generation. I managed to do the TextBoxes (and the DatePicker, excluded from this code) but I'm struggling to bind the ComboBox to the enum.
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'm doing 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 the MainPage.xaml, in the Grid:
<dataFormToolkit:DataForm x:Name="myDataForm" AutoEdit="False" AutoCommit="False"
Header="Foo Movie DB">
</dataFormToolkit:DataForm>
for the auto-generated stuff. When trying to generate it manually, I've instead 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 the ComboBox doesn't work. There are a lot of articles covering this but it seems that much of what they propose is too much for an auto-generator to do (e.g. subclassing ComboBox to provide SelectedValue). Do you know how the tools do it for us?
You can do this using 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 could pass the full type name to GenreConverter to make this generic for any enum
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With