2009-12-30 3 views
6

Sto cercando di capire DataForm come implementato nel toolkit di novembre 2009 e non riesco a capire come associare un ComboBox a un enum. Qualcuno sa come il DataForm fa questo automaticamente?In che modo Silverlight DataForm genera automaticamente un'associazione da un ComboBox a un enum?

Sfondo

Per prima cosa ho creato una classe e un Enum, seguendo this articolo e ha permesso il DataForm per generare i campi. DataForm ha generato un controllo TextBox per il campo stringa Nome e (cosa presumo che sia) un ComboBox per il campo enum Generi.

Il mio primo obiettivo nel capire come personalizzare il DataForm è riprodurre ciò che viene prodotto nella generazione automatica. Sono riuscito a fare i TextBoxes (e il DatePicker, escluso da questo codice) ma ho difficoltà a legare il ComboBox all'enum.

Qui ci sono le classi (semplificato):

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

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

e poi in MainPage sto facendo questo:

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

e nel MainPage.xaml, nella Griglia:

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

per le cose generate automaticamente. Quando provo a generarlo manualmente, ho invece ottenuto:

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

ma il ComboBox non funziona. Ci sono molti articoli che trattano questo, ma sembra che gran parte di ciò che propongono sia troppo per fare un auto-generatore (ad esempio la sottoclasse di ComboBox per fornire SelectedValue). Sai come gli strumenti lo fanno per noi?

risposta

4

Questo è il codice che esegue 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

È possibile farlo usando 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"); 
     } 
    } 
} 

Converti da Enum alla lista per 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;    
    } 

e convertire da stringa torna alla lista:

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

Si potrebbe passare il nome di tipo completo per GenreConverter per rendere questo generico per qualsiasi enum

+0

Sembra che si potrebbe usare la vostra prima upvote ... buona risposta . – mkedobbs

+0

È una buona risposta dettagliata ma non ho chiesto come potrei farlo, ho chiesto come lo fa DataForm, quindi non l'ho accettato come risposta. – serialhobbyist