О виртуализации данных в WPF можно прочитать в WPF: виртуализация данных.
При использовании этого виртуализация данных была выполнена в моем коде так же хорошо, но есть одна проблема, заключающаяся в том, что я не могу связать свойство в ViewModel с SelectedItem из ItemsControl в представлении. Если один элемент данных удовлетворяет некоторому условию во время загрузки данных, этот элемент будет установлен как свойство в ViewModel, а затем он будет связан с SelectedItem из ItemsControl в представлении, но не будет.
Мой код об этом следующий. О типах IItemsProvider и VirtualizingCollection см. в документе WPF: виртуализация данных.
До сих пор я пробовал:
- Я уверен, что если бы виртуализация данных не использовалась, привязка выбранных элементов была бы крутой.
- Метод IndexOf(T item) в VirtualizingCollection всегда возвращает -1. Думая, что это может быть проблемой, я реализовал, что элемент IndexOf(T) возвращает фактический индекс, но это не касалось этой проблемы.
Код реализации IItemsProvider
public class WordViewModelProvider : IItemsProvider<WordViewModel>
{
private string _searchText = "some text";
public WordViewModel SelectedItem
{
get;
private set;
}
#region IItemsProvider<WordViewModel> Members
public int FetchCount()
{
lock (_words)
{
int count = (from word in _words
where word.Name.Contains(_searchText)
select word).Count();
return count;
}
}
public IList<WordViewModel> FetchRange(int startIndex, int count)
{
lock (_words)
{
//Please, regard _word as IEnumerable<Word>
IQueryable<Word> query = (from word in _words
where word.Name.Contains(_searchText)
select word);
List<WordViewModel> result = query.ToList().ConvertAll(w =>
{
var wordViewModel = new WordViewModel(w, _searchText);
if (w.Name.Equals(_searchText, StringComparison.InvariantCultureIgnoreCase))
{
SelectedItem = wordViewModel;
}
return wordViewModel;
});
return result;
}
}
#endregion
}
Код использования VirtualizingCollection в ViewModel
public void ViewList()
{
var wordViewModelProvider = new WordViewModelProvider();
var virtualizingCollection = new VirtualizingCollection<WordViewModel>(wordViewModelProvider);
//IList<WordViewModel> type to bind with View's ItemsSource.
WordViewModels = virtualizingCollection;
//WordViewModel type to bind with View's SelectedItem
SelectedItem = wordViewModelProvider.SelectedItem;
}