WPFのデータ仮想化について、WPF:データ仮想化は良い記事です。
これを使用すると、データ仮想化は私のコードで適切に実行されましたが、1つの問題があります。それは、ViewModelのプロパティをViewのItemsControlのSelectedItemにバインドできないことです。データの読み込み中に1つのデータ項目が何らかの条件を満たす場合、その1つの項目はViewModelのプロパティとして設定され、ViewのItemsControlのSelectedItemにバインドされますが、バインドされません。
これに関する私のコードは次のとおりです。IItemsProviderとVirtualizingCollectionの種類については、WPF:データ仮想化を参照してください。
これまでのところ、私は試しました:
- データ仮想化が使用されなかった場合、選択されたアイテムのバインドはクールになると確信しています。
- VirtualizingCollectionのIndexOf(T item)メソッドは、常に-1を返します。これが問題になると考えて、IndexOf(T item)が実際のインデックスを返すように実装しましたが、この問題には関係ありませんでした。
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
}
ViewModelでVirtualizingCollectionを使用するコード
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;
}