2009-12-30 7 views
6

Próbuję zrozumieć DataForm, jak zaimplementowano w pakiecie narzędziowym z listopada 2009 r. I nie mogę się dowiedzieć, jak powiązać ComboBox z wyliczeniem. Czy ktoś wie, jak DataForm robi to automatycznie?W jaki sposób Silverlight DataForm automatycznie generuje powiązanie z ComboBox do wyliczenia?

Tło

Najpierw stworzyłem klasę i wyliczenia, następujące this artykułu i pozwolił DataForm do generowania pola. DataForm wygenerował TextBox dla pola String nazwy i (jak przypuszczam) ComboBox dla pola wyliczenia Genres.

Moim pierwszym celem w zrozumieniu sposobu dostosowywania DataForm jest odtworzenie tego, co powstaje podczas automatycznego generowania. Udało mi się zrobić TextBoxes (i DatePicker, wyłączone z tego kodu), ale staram się związać ComboBox z wyliczeniem.

Oto Klasy (uproszczony):

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

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

a następnie w mainpage Robię to:

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

aw MainPage.xaml w Grid:

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

w przypadku materiałów wygenerowanych automatycznie. Próbując wygenerować go ręcznie, otrzymałem:

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

, ale ComboBox nie działa. Istnieje wiele artykułów na ten temat, ale wydaje się, że wiele z tego, co proponują, to zbyt wiele, aby mógł to zrobić auto-generator (np. Podklasy ComboBox w celu zapewnienia SelectedValue). Czy wiesz, jak narzędzia to dla nas robią?

Odpowiedz

4

Jest to kod, który wykonuje 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; 
5

Można to zrobić przy użyciu 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"); 
     } 
    } 
} 

przekonwertować z Enum do listy dla 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;    
    } 

i Konwersja z ciąg powrót do listy:

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

Można by przejść do pełnej nazwy typu GenreConverter aby ten rodzajowy dla każdego wyliczenia

+0

Wygląda można użyć najpierw upvote ... dobrą odpowiedź . – mkedobbs

+0

To dobra, szczegółowa odpowiedź, ale nie pytałem, jak to zrobić, zapytałem, jak robi to DataForm, więc nie zaakceptowałem jej jako odpowiedzi. – serialhobbyist

Powiązane problemy