6

我试图理解 DataForm 在 2009 年 11 月的工具包中实现,但我不知道如何将 ComboBox 绑定到枚举。有谁知道 DataForm 是如何自动执行此操作的?

背景

首先,我按照这篇文章创建了一个类和一个 Enum,并允许 DataForm 生成字段。DataForm 为 Name 字符串字段生成了一个 TextBox,并且(我假设是)为 Genres 枚举字段生成了一个 ComboBox。

我了解如何自定义 DataForm 的第一个目标是重现自动生成中产生的内容。我设法完成了 TextBoxes(和 DatePicker,从这段代码中排除),但我正在努力将 ComboBox 绑定到枚举。

以下是类(简化):

public class Movie
{
    public string Name { get; set; }
    public Genres Genre { get; set; }
}

public enum Genres
{
    Comedy,
    Fantasy,
    Drama,
    Thriller
}

然后在 MainPage 我这样做:

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;
}

在 MainPage.xaml 的网格中:

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

对于自动生成的东西。当尝试手动生成它时,我得到了:

<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>

但组合框不起作用。有很多文章涵盖了这一点,但似乎他们提出的大部分内容对于自动生成器来说太多了(例如,将 ComboBox 子类化以提供 SelectedValue)。你知道这些工具是如何为我们做的吗?

4

2 回答 2

5

您可以使用 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");
        }
    }
} 

从 Enum 转换为 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;            
    }

并从字符串转换回列表:

    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);
    }
}

您可以将完整的类型名称传递给 GenreConverter 以使其对任何枚举都具有通用性

于 2010-01-11T00:59:48.313 回答
4

这是 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;
于 2010-02-04T17:48:15.210 回答