Search code examples
data-bindingsilverlight-3.0comboboxenumsdataform

How does a Silverlight DataForm auto-generate a binding from a ComboBox to an enum?


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?


Solution

  • This is the code that DataForm executes...

    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;