Modo de seleção estendida, virtualização e ligação IsSelected

Parece no modo de seleção estendidaIsSelected encadernação é com erros. Parece apenas o último item da seleção que se tornafora de escopo é tratado corretamente.

Demonstração:

Itens0, 1, 2 e98, 97, 96 são selecionados comAo controle. Ao selecionar94 (semAo controle!) contador de seleção deve ser1, mas você vê3 em vez de. A rolagem para cima revela que apenas um (último) item de seleção fora do escopo foi desmarcado.

Abaixo está o mcve:

xaml:

<ListBox ItemsSource="{Binding Items}" SelectionMode="Extended" SelectionChanged="ListBox_SelectionChanged">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Text}" />
        </DataTemplate>
    </ListBox.ItemTemplate>
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="IsSelected" Value="{Binding IsSelected}" />
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

cs:

public class NotifyPropertyChanged : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged([CallerMemberName] string property = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
}

public class Item : NotifyPropertyChanged
{
    bool _isSelected;
    public bool IsSelected
    {
        get { return _isSelected; }
        set { _isSelected = value; }
    }

    public string Text { get; set; }
}

public class ViewModel : NotifyPropertyChanged
{
    public ObservableCollection<Item> Items { get; }

    public ViewModel()
    {
        var list = new List<Item>();
        for (int i = 0; i < 100; i++)
            list.Add(new Item() { Text = i.ToString() });
        Items = new ObservableCollection<Item>(list);
    }
}

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new ViewModel();
    }

    void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        Title = ((ViewModel)DataContext).Items.Count(item => item.IsSelected).ToString();
    }
}

Uma solução rápida é desativar o controle de lista (ListBox ouListView) virtualização:

VirtualizingStackPanel.IsVirtualizing="False"

Pergunta: alguma idéia de como corrigi-lo sem desativar a virtualização?

questionAnswers(1)

yourAnswerToTheQuestion