これは私のプロジェクトでやったことです(私は無限のスクロールでリストビューを持っています)。基本的に、私は自分で仮想化の一部をしました。
DataTemplateSelector
を完全に削除しました。代わりに、私はすべての項目に対して1つのテンプレートを使用し:
MyCustomContainer
は、単純なユーザーコントロールです
<ListView
...
>
<ListView.ItemTemplate>
<DataTemplate>
<messages:MyCustomContainer />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
:
<UserControl
x:Class="MyCustomContainer"
...
DataContextChanged="OnDataContextChanged"
>
<Grid x:Name="Container"/>
</UserControl>
私はインスタンス化しMyCustomContainer
の背後にあるコードに適切なネストされたテンプレートを選択します。
void OnDataContextChanged(FrameworkElement sender, DataContextChangedEventArgs args)
{
var context = DataContext as MyModelThatHelpsDecideOnAppropriateVisualTemplate;
if (context == null) {
// this means, item has been removed from the list and cached (we call this 'virtualization')
Container.Children.Remove(CurrentTemplate);
ReleaseTemplate(CurrentTemplate); // clear and cache our concrete template
CurrentTemplate = null;
} else {
// this means, we need to get a concrete template
// ... some logic to decide on the proper visual template type
Type templateType = GetTemplateTypeForData(context);
// ... some logic to get visual template from cache
CurrentTemplate = GetTemplateFromCache(templateType);
Container.Children.Add(CurrentTemplate);
}
}
明るいところでは、これはうまくいきます(私にはありますが、約12個のアイテムテンプレートがあります)。
このように、UIフレームワークはMyCustomContainer
のリスト項目のみを仮想化するため、具体的なビジュアルを自分でキャッシュする必要があります。私の例では、あなたの10-15テンプレートのインスタンスをいくつかのキャッシュに保存し、GetTemplateTypeForData()
,GetTemplateFromCache()
、ReleaseTemplate()
を実装する必要があります...しかし、それは本当に簡単で、100行ほどのコードが必要でした。
本当に10-15の異なるデータテンプレートが必要ですか?データ型では、パネルとコントロールの可視性を設定できるので、たとえば、各行の現在のデータコンテキストに基づいて異なる情報を表示するItemTemplateを1つだけ持つことができます。 –
はい。テキスト、日付ピッカー、チェックボックス、コンボボックス、ラジオボタン、テーブルなど、入力コントロールの異なるアンケートのようなものです。ViewModelsには異なるロジック(たとえば、回答の読み込みと保存の方法)があります。したがって、1つのビューモデルでそれを混在させるのは良いことではありません... –