2010-05-28 32 views
3

J'ai un comportement vraiment strage. J'ai un ListBox dans la vue avec un DataTemplate pour ses articles, y compris ViewModels. Je lie le IsSelected à mon ViewModel et utilise SelectionMode = "Extended". Tout fonctionne bien. MAIS si j'ajoute VirtualiuationMode = "Recycling", j'obtiens les mauvais éléments. Pour reproduire: sélectionnez les éléments avec Ctrl, puis faites défiler vers le bas et sélectionnez un seul élément. Le comportement normal désélectionne tous les éléments et sélectionne simplement le dernier sans Ctrl enfoncé. Mais si je consulte mon ViewModel, tous les anciens éléments sont sélectionnés!?!Mauvaise sélection dans ListBox avec VirtualizationMode = "Recycling" et SeclectionMode = "Extended"?

<Grid> 
    <StackPanel> 
     <ListBox ItemsSource="{Binding People}" MaxHeight="100" 
       SelectionMode="Extended" 
       VirtualizationMode="Recycling"> 
      <!--VirtualizingStackPanel.IsVirtualizing="True">--> 

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

       </Style> 

      </ListBox.ItemContainerStyle> 
      <ListBox.ItemTemplate> 
       <DataTemplate> 

        <views:PeopleView /> 

       </DataTemplate> 

      </ListBox.ItemTemplate> 
     </ListBox> 
     <Button Click="Button_Click"> 
      OK 
     </Button> 
    </StackPanel> 
</Grid> 

Le modèle d'élément

<UserControl x:Class="WpfApplication1.View.PeopleView" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Height="Auto" Width="Auto"> 
<Grid> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="Auto" SharedSizeGroup="A"/> 
     <ColumnDefinition Width="Auto" SharedSizeGroup="B"/> 
    </Grid.ColumnDefinitions> 
    <TextBox Text="{Binding Path=Name}" 
      Name="tbx_Name" 
      Grid.Column="0"/> 

    <CheckBox IsChecked="{Binding Path=IstAktiv}" 
     Name="cbx_IstAktiv" 
       Grid.Column="1"/> 

</Grid> 

Toute idée?

+0

Petite erreur le code: VirtualizingStackPanel.VirtualizationMode = "Recyclage" Mais j'ai encore le problème ... – KCT

Répondre

1

J'ai une solution de contournement mais pourquoi dois-je la changer "manuellement" dans l'événement de changement et non par liaison de données?

private void Lbx_SelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     ListBox lbx = (ListBox)sender; 
     foreach (PersonViewModel item in lbx.Items) 
     { 
      item.IsSelected = lbx.SelectedItems.Contains(item); 
     } 
    } 
1

Une autre option liée à la réponse précédente de KCT est d'utiliser le AddedItems et RemovedItems de la SelectionChangedEventArgs et de cibler les changements, tels que:

private void Lbx_SelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
    foreach (var item in e.AddedItems) 
    { 
     ((PersonViewModel)item).IsSelected = true; 
    } 
    foreach (var item in e.RemovedItems) 
    { 
     ((PersonViewModel)item).IsSelected = false; 
    } 
} 

Cela peut donner de meilleures performances avec des collections plus grandes (I » Il y a environ 15 000 entrées dans un panneau Virtualisation Tile dans un ListBox).