2016-07-28 12 views
0

異なるアイテム(合計10-15アイテムタイプ)のリストビューを表示する必要があります。このため私はDataTemplateSelectorを使用します。しかし、これは、スクロール時にListViewの奇妙な動作を引き起こします。ある時点で、リストビューの先頭にジャンプします。私はこの記事をUWPのために見つけました:https://msdn.microsoft.com/en-us/windows/uwp/debug-test-perf/optimize-gridview-and-listview。 ItemTemplateSelectorは5つのDataTemplateのみをサポートしますWinRTリストビューUI仮想化とたくさんのテンプレートを持つDataTemplateSelector(10-15)

さらに、アイテムテンプレートセレクタは、現在のデータアイテムに対して特定のコンテナを再利用できるかどうかを評価する際に5つの候補を検討します。

私はこれが理由だと思います。私はDataTemplateSelectorによって返されるDataTemplateの数を減らそうとしましたが、問題は解決しました。スクロールは期待通りに機能します。しかし、DataTemplateの数を減らさずにこの問題を解決するにはどうすればよいですか?私は仮想化を無効にできることを知っていますが、可能であれば有効にしておきたいと思います。

UWPの場合、ChoosingItemContainerイベントを使用するオプションがありますが、WinRTでは使用できません。

WinRTでUI仮想化を無効にしないとこの問題を解決できますか?

+0

本当に10-15の異なるデータテンプレートが必要ですか?データ型では、パネルとコントロールの可視性を設定できるので、たとえば、各行の現在のデータコンテキストに基づいて異なる情報を表示するItemTemplateを1つだけ持つことができます。 –

+0

はい。テキスト、日付ピッカー、チェックボックス、コンボボックス、ラジオボタン、テーブルなど、入力コントロールの異なるアンケートのようなものです。ViewModelsには異なるロジック(たとえば、回答の読み込みと保存の方法)があります。したがって、1つのビューモデルでそれを混在させるのは良いことではありません... –

答えて

1

これは私のプロジェクトでやったことです(私は無限のスクロールでリストビューを持っています)。基本的に、私は自分で仮想化の一部をしました。

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行ほどのコードが必要でした。