Question

I ai mis en oeuvre un modèle de sélection similaire à celui décrit dans cette publication à l'aide un ViewModel pour enregistrer la valeur IsSelected, et en liant le ListViewItem.IsSelected à la ViewModel IsSelected:

<ListView.ItemContainerStyle>
    <Style TargetType="{x:Type ListViewItem}">
        <Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}"/>
    </Style>
</ListView.ItemContainerStyle>

Il fonctionne en général, mais je rencontre un problème grave. En utilisant l'un VirtualizingStackPanel que le panneau dans la vue de la liste, OBTIENNENT créé seulement le ListViewItem visible. Si je l'utilise « Ctrl + A » pour sélectionner tous les éléments, ou en utilisant la combinaison de raccourcis tels « Shift + Ctrl + Fin » sur le premier élément, tous les éléments se sélectionnés, mais pour les éléments non visibles, le ViewModel ne détienne pas IsSelected la valeur true. Ce qui est logique, car si le ListViewItem ne sont pas créés, la liaison ne peut pas travailler.

Tout le monde a connu le même problème, et a trouvé une solution (à l'exception de ne pas utiliser un VirtualizingStackPanel)?

Était-ce utile?

La solution

J'ai trouvé une autre façon de gérer la sélection dans le modèle MVVM, qui a résolu mon problème. Au lieu de maintenir la sélection dans la viewmodel, la sélection est extraite de la ListView / ListBox et passé en paramètre à la commande. Tout est fait en XAML:

<ListView 
    x:Name="_items"
    ItemsSource="{Binding Items}" ... />

<Button 
    Content="Remove Selected" 
    Command="{Binding RemoveSelectedItemsCommand}" 
    CommandParameter="{Binding ElementName=_items, Path=SelectedItems}"/>

dans mon ViewModel:

private void RemoveSelection(object parameter)
{
    IList selection = (IList)parameter;
    ...
}

Autres conseils

Dans mon cas, j'ai fini par résoudre ce en dérivant une classe ListBoxEx de ListBox, et en ajoutant du code pour répondre aux changements de sélection, l'application de l'état de sélection sur les modèles de vue de l'article:

private readonly List<IListItemViewModelBase> selectedItems = new List<IListItemViewModelBase>();

protected override void OnSelectionChanged(SelectionChangedEventArgs e)
{
    base.OnSelectionChanged(e);

    bool isVirtualizing = VirtualizingStackPanel.GetIsVirtualizing(this);
    bool isMultiSelect = (SelectionMode != SelectionMode.Single);

    if (isVirtualizing && isMultiSelect)
    {
        var newSelectedItems = SelectedItems.Cast<IListItemViewModelBase>();

        foreach (var deselectedItem in this.selectedItems.Except(newSelectedItems))
        {
            deselectedItem.IsSelected = false;
        }

        this.selectedItems.Clear();
        this.selectedItems.AddRange(newSelectedItems);

        foreach (var newlySelectedItem in this.selectedItems)
        {
            newlySelectedItem.IsSelected = true;
        }
    }
}

En dehors de ne pas utiliser VirtualizingStackPanel, la seule chose que je peux penser est de capturer ces raccourcis clavier et ont des méthodes pour modifier un certain nombre de vos articles de ViewModel afin que leur propriété IsSelected est réglé sur True (par exemple, SelectAll(), SelectFromCurrentToEnd()) . Fondamentalement, sans passer par le Binding sur ListViewItem pour contrôler la sélection de tels cas.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top