2010-05-28 2 views
3

나는 정말로 행동을 취한다. ViewModels 등의 항목에 대해 DataTemplate이있는 ListBox가 있습니다. 내 ViewModel에 IsSelected를 바인딩하고 SelectionMode = "Extended"를 사용합니다. 모든 것이 잘 작동합니다. 그러나 VirtualiuationMode = "Recycling"을 추가하면 잘못된 항목이 표시됩니다. 재생하려면 : Ctrl 키를 사용하여 항목을 선택한 다음 아래로 스크롤하여 하나의 항목 만 선택하십시오. 정상적인 동작은 모든 항목의 선택을 취소하고 Ctrl 키를 누르지 않고 마지막 항목을 선택하기 만하면됩니다. 그러나 ViewModel을 검사하면 모든 이전 항목이 선택됩니다!ListBox에서 VirtualizationMode = "Recycling"및 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> 

항목 템플릿

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

어떤 생각?

+0

작은 실수 그것은 코드 : VirtualizingStackPanel.VirtualizationMode = "재활용" 하지만 여전히 문제가 ... – KCT

답변

1

해결 방법이 있는데 왜 데이터 바인딩이 아닌 변경 이벤트에서 "수동"으로 변경해야합니까? '(I

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

이 큰 컬렉션에 더 나은 성능을 제공 할 수 있습니다 : KCT의 이전 응답에 관련된

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

또 다른 옵션은 SelectionChangedEventArgs에서 AddedItemsRemovedItems을 사용하고 다음과 같은 변화를 목표로하는 것입니다 ListBox에있는 Virtualizing Tile Panel에 약 15,000 개의 항목이 있습니다.)