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