2010-01-14 11 views
5

Tengo un ViewModel que tiene una propiedad que IsSelected Ato en mi ListView.ItemContainerStyle XAML a un IsSelected propiedad en mi modelo de vista.WPF Encuadernación IsSelected al modelo de vista no establece los elementos que no se han mostrado en la Lista

que aparezca la solicitud y rellenar la colección vista del modelo (que se muestra en mi ListView) con una gran cantidad de artículos, digamos alrededor de 2000. Luego seleccione todo en la lista a través de Ctrl-A. Los elementos en mi colección de modelos de vista solo obtienen el IsSelected establecido para los artículos que están visibles en el ListView. Si navego por la lista, el IsSelected se configura para los elementos que se muestran. Si visualizo todos los elementos, todos los elementos de mi modelo de vista tienen la propiedad IsSelected establecida en verdadero.

Aquí es mi XAML para la unión del IsSelected en la vista de lista a mi vista del modelo:

<ListView Margin="5" ItemsSource="{Binding FilteredComparisonList}" x:Name="comparisonListView"> 
    <ListView.ItemContainerStyle> 
     <Style TargetType="{x:Type ListBoxItem}"> 
      <Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}" /> 
     </Style> 
    </ListView.ItemContainerStyle> 
    <ListView.View> 
     <GridView> 
      <GridViewColumn Header="Source filename" DisplayMemberBinding="{Binding ImageFile.BaseFilename}" Width="Auto" /> 
     </GridView> 
    </ListView.View> 
</ListView> 

¿Por qué no es IsSelected para todos los artículos en mi modelo de vista establecidas en true cuando selecciono todas las partidas en el ListView?

+0

Por cierto, esta es esencialmente la misma pregunta que esta: http://stackoverflow.com/questions/1273659/virtualizingstackpanel-mvvm-multiple-selection – Charlie

+0

Gracias Charlie, no sé cómo me perdí esa publicación. Esa publicación tiene una buena solución para este problema, que consiste en pasar los elementos seleccionados como un parámetro de comando en lugar de mantener IsSelected en el modelo de vista. – Buck

Respuesta

3

Esto sucede debido a la virtualización integrada de ListView. Si no estás familiarizado con eso, lo que básicamente significa es que los elementos no se vuelven reales hasta que estén a la vista. Se puede desactivar la virtualización del ListView con la siguiente propiedad:

VirtualizingStackPanel.IsVirtualizing="False" 

Pero cuidado que esto tendrá un efecto adverso en el rendimiento de su ListView. Para 2,000 artículos no será severo, pero podría ser notable.

2

Los elementos de ListBoxItem están virtualizados, no existen hasta que se generan (cuando se visualizan). Sin embargo, el ListView subyacente se deriva de ListBox que tiene una propiedad SelectedItems. Los elementos seleccionados son una lista de todos los elementos seleccionados, no una lista de los elementos de ListBox que están seleccionados. Cuando se muestra el ListBoxItem, su propiedad IsSelected se establece en función de si su artículo (el elemento que muestra) está en la colección de SelectedItems.

Este es un problema para su modelo de vista, especialmente si necesita que la virtualización esté activada (lo que probablemente haga para 2000 o más elementos). Me interesaría la respuesta a la pregunta "¿Cómo vinculo mi propiedad isSelected de los modelos de vista en función de si un artículo está en la colección SelectedItems de ListBox?"

la respuesta probablemente implica un convertidor

4

La forma MVVM para hacer esto sería para anular el acceso directo Ctrl-A con su propio comando Seleccionar Todo (Crear un comando SellectAll con un atajo de Ctrl-A). La implementación establecerá IsSelected en los modelos de vista.

Su propiedad IsSelected en su vista debe tener un enlace de dos vías a su modelo de vista para que los elementos aparezcan seleccionados en su vista.

No creo que sea necesario apagar la virtualización.

Espero que esto ayude.

0

que tenían el mismo problema y eso es lo que me ayudó finalmente:

poner en su ListView:

VirtualizingStackPanel.VirtualizationMode="Standard" 
0

voy a publicar esta respuesta que he encontrado en un foro diferente, ya que me ayudó con la cuestión.

he definido una interfaz ISelectable para mis ViewModels para implementar

public interface ISelectable 
{ 
    bool IsSelected { get; set; } 
} 

Luego, en MyCustomListView me han hecho esto:

public class MyCustomListView : ListView 
{ 
    protected override void OnSelectionChanged(SelectionChangedEventArgs e) 
    { 
     foreach (var item in e.AddedItems.OfType<ISelectable>()) 
      item.IsSelected = true; 

     foreach (var item in e.RemovedItems.OfType<ISelectable>()) 
      item.IsSelected = false; 

     base.OnSelectionChanged(e); 
    } 
} 

Alternativamente, se puede hacer suscribirse al evento SelectionChanged del ListView y usa el mismo código de arriba

Cuestiones relacionadas