2010-11-04 21 views
3

Je suis relativement nouveau à l'idée de WPF et MVVM et je recherche des conseils sur une meilleure pratique. J'ai une solution qui fonctionne mais il me semble que je pourrais manquer une bonne syntaxe XAML qui simplifierait le tout.WPF, relier un CSV à une liste de cases à cocher, et les meilleures pratiques MVVM

J'ai un champ de chaîne dans une table de base de données qui est stockée en tant que fichier CSV, par ex. "CHAT CHIEN". J'aurais peut-être dû faire cela comme une relation plusieurs-à-plusieurs dans mon modèle de données d'entité, mais c'est une discussion différente sur les meilleures pratiques.

Dans mon code XAML, j'utilise une liaison multiple sur un ListBox qui contient des CheckBox. Le domaine des choix possibles est déterminé au moment de l'exécution et ListBox génère des CheckBox à l'aide d'un DataTemplate. Voici le code XAML:

<ListBox Grid.Column="3" Grid.Row="8" Grid.RowSpan="2" Name="brandedProductsListBox" Margin="3" ItemsSource="{Binding Source={StaticResource brandedProductLookup}}" IsSynchronizedWithCurrentItem="True" TabIndex="475"> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <CheckBox Margin="3" Content="{Binding Path=BrandedProductName}" Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked"> 
       <CheckBox.IsChecked> 
        <MultiBinding Converter="{StaticResource brandedProductToBoolean}"> 
         <Binding Source="{StaticResource projectsView}" Path="BrandedProducts" /> 
         <Binding Path="BrandedProductName" /> 
        </MultiBinding> 
       </CheckBox.IsChecked> 
      </CheckBox> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ListBox> 

J'utilise un convertisseur pour vérifier les CheckBox appropriés. J'ai essayé d'obtenir la méthode ConvertBack du convertisseur pour transformer un booléen dans ma chaîne de CSV, mais je ne pourrais pas comprendre comment obtenir l'accès BrandedProductName quand tout ce que j'ai été passé était un booléen. Voici le convertisseur:

public class BrandedProductToBooleanConverter : IMultiValueConverter 
{ 
    public object Convert(object[] value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (value == null) { 
      return false; 
     } 
     else { 
      // The bindings passed in (in order) are: the BrandedProducts field for the current project, 
      // and the Branded Product represented by the current CheckBox. 
      string brandedProducts = value[0] as string; 
      string brandedProduct = value[1] as string; 
      return brandedProducts == null ? false : brandedProducts.Contains(brandedProduct); 
     } 
    } 

    public object[] ConvertBack(object value, Type[] targetType, object parameter, CultureInfo culture) 
    { 
     return null; 
    } 
} 

Convert Ainsi vérifie correctement les bonnes cases à cocher lorsqu'une entité est sélectionnée, mais l'ajout d'un nouveau je me suis dit que je pouvais utiliser les gestionnaires d'événements enregistrés et non enregistrés du CheckBox à écrire de nouveau à mon entité, comme si:

 private void CheckBox_Checked(object sender, RoutedEventArgs e) 
    { 
     if (projectView.IsAddingNew) { 
      CheckBox checkBox = sender as CheckBox; 
      NewProject project = projectView.CurrentAddItem as NewProject; 
      if (project.BrandedProducts == null) { 
       project.BrandedProducts = (string)checkBox.Content; 
      } 
      else { 
       project.BrandedProducts += ", " + (string)checkBox.Content; 
      } 
     } 
     e.Handled = true; 
    } 

    private void CheckBox_Unchecked(object sender, RoutedEventArgs e) 
    { 
     if (projectView.IsAddingNew) { 
      CheckBox checkBox = sender as CheckBox; 
      NewProject project = projectView.CurrentAddItem as NewProject; 
      if (project.BrandedProducts != null) { 
       project.BrandedProducts = project.BrandedProducts.Replace((string)checkBox.Content + ", ", "").Replace(", " + (string)checkBox.Content, ""); 
      } 
     } 
     e.Handled = true; 
    } 

Si vous êtes toujours avec moi, la question est de savoir quelle est la meilleure façon de le faire? Cela ressemble un peu à des pommes et des oranges avec moi utilisant un convertisseur pour générer la vue à partir de l'entité mais utilisant ensuite des gestionnaires d'événements pour traduire les mises à jour/commandes de vue à l'entité. Est-ce que cela viole un objectif de MVVM d'utiliser des gestionnaires d'événements pour modifier mon ViewModel de cette façon?

Merci à l'avance pour toute suggestion, Ray

Si vous êtes toujours avec moi

Répondre

1

Ray,

, la question est ce qui est une meilleure façon de le faire?

J'ai trouvé que, avec WPF, si vous vous posez cette question, il est probablement une meilleure façon. Il y a juste tellement d'options (par rapport à Wimpy WinForms).

-t-il un but de violer MVVM à gestionnaires d'événements d'utiliser pour modifier mon ViewModel cette façon?

À mon humble avis, oui, il viole MVVM. Vous ne devriez pas avoir de code ViewModel (en plus de configurer une liaison ViewModel) dans votre code-behind.

Vos événements doivent exécuter ICommand (s) qui sont exposés par votre ViewModel (c'est-à-dire Ajouter, Supprimer). Voir le EventToCommand qui s'appliquerait probablement à vos événements CheckBox_Checked et CheckBox_UnChecked.

-jberger