【问题标题】:How does a Silverlight DataForm auto-generate a binding from a ComboBox to an enum?Silverlight DataForm 如何自动生成从 ComboBox 到枚举的绑定?
【发布时间】:2009-12-30 14:34:35
【问题描述】:

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

背景

首先我按照this 文章创建了一个类和一个枚举,并允许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 中,在 Grid 中:

<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)。你知道这些工具是如何为我们做的吗?

【问题讨论】:

    标签: data-binding silverlight-3.0 combobox enums dataform


    【解决方案1】:

    您可以使用 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 以使其对任何枚举都具有通用性

    【讨论】:

    • 这是一个很好的详细答案,但我没有问我怎么做,我问DataForm是如何做到的,所以我没有接受它作为答案。
    【解决方案2】:

    这是 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;
    

    【讨论】:

      猜你喜欢
      • 2011-07-03
      • 1970-01-01
      • 2010-12-21
      • 2015-07-03
      • 2016-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-03
      相关资源
      最近更新 更多