6

2009年11月のツールキットに実装されているDataFormを理解しようとしていますが、ComboBoxを列挙型にバインドする方法がわかりません。DataFormがこれを自動的に行う方法を知っている人はいますか?

バックグラウンド

最初に、この記事に従ってクラスと列挙型を作成し、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を提供するためにComboBoxをサブクラス化する)。ツールが私たちのためにそれをどのように行うか知っていますか?

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

列挙型から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 に答える