Pregunta

He implementado un patrón de selección similar a la descrita en este post el uso de un ViewModel para almacenar la IsSelected valor, y mediante la unión de la ListViewItem.IsSelected a la Perspective IsSelected:

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

Funciona en general, pero me encuentro con un grave problema.Mediante el uso de la un VirtualizingStackPanel como el panel en la vista de lista, sólo visible ListViewItem está siendo creado.Si puedo usar "Ctrl+a" para seleccionar todos los elementos, o mediante la combinación de teclas tales "Mayús+Ctrl+Fin" en el primer ítem, todos los artículos seleccionados, pero para los que no los elementos visibles, el ViewModel no obtener su IsSelected establece en true.Es lógico, porque si la ListViewItem no se crean, la unión no puede trabajar.

Nadie experimentado el mismo problema y encontrar una solución (aparte de no usar un VirtualizingStackPanel)?

¿Fue útil?

Solución

He encontrado otra manera de manejar la selección en el patrón MVVM, que resolvió mi problema. En lugar de mantener la selección en el modelo de vista, la selección se recupera de la ListView / ListBox, y pasa como parámetro al comando. Todo hecho en XAML:

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

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

en mi modelo de vista:

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

Otros consejos

En mi caso, terminé la solución de este derivando una clase ListBoxEx de ListBox, y la adición de código para responder a los cambios de selección, hacer cumplir el estado de selección de los modelos de vista del elemento:

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

Además de no usar VirtualizingStackPanel, lo único que puedo pensar es capturar esos atajos de teclado y tienen métodos para modificar una determinada gama de sus artículos ViewModel modo que su propiedad IsSelected se establece en True (por ejemplo, SelectAll(), SelectFromCurrentToEnd()) . Básicamente sin pasar por el Binding en ListViewItem para el control de la selección para estos casos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top