2016-07-28 4 views
0

다른 항목 (총 10-15 개의 항목 유형)으로 ListView를 표시해야합니다. 이를 위해 DataTemplateSelector를 사용합니다. 그러나 이로 인해 스크롤하는 동안 ListView가 비정상적으로 작동합니다. 어떤 시점에서 목록보기의 맨 위로 이동합니다. UWP에 대한이 기사를 발견했습니다 : https://msdn.microsoft.com/en-us/windows/uwp/debug-test-perf/optimize-gridview-and-listview. ItemTemplateSelector는 5 개의 DataTemplate 만 지원합니다.WinRT 많은 템플릿이있는 ListView UI 가상화 및 DataTemplateSelector (10-15)

또한 항목 템플릿 선택기는 특정 컨테이너를 현재 데이터 항목에 대해 재사용 할 수 있는지 여부를 평가할 때 5 가지 가능한 후보를 고려합니다.

나는 이것이 이유라고 생각한다. 내 DataTemplateSelector에 의해 반환 된 DataTemplates 수를 줄이려고했는데 문제가 해결 된 : 스크롤 예상대로 작동합니다. 그러나 DataTemplate의 수를 줄이지 않고도이 문제를 어떻게 해결할 수 있습니까? 나는 가상화를 비활성화 할 수 있음을 알고 있지만 가능하다면 가상화를 활성화하고 싶습니다.

UWP의 경우 ChoosingItemContainer 이벤트를 사용하는 옵션이 있지만 WinRT에는 사용할 수 없습니다.

WinRT에서 UI 가상화를 사용하지 않으면이 문제를 해결할 수 있습니까?

+0

정말 10-15 개의 다른 데이터 템플릿이 필요합니까? 데이터 템플릿에서 패널과 컨트롤의 가시성을 설정할 수 있으므로 예를 들어 각 행의 현재 데이터 중심에 따라 서로 다른 정보를 표시하는 ItemTemplate을 하나만 가질 수 있습니다. –

+0

예. 텍스트, 날짜 표시기, 체크 박스, 콤보 박스, 라디오 버튼, 테이블 등 다양한 입력 컨트롤을 가진 설문지와 같은 것입니다. ViewModels는 다른 논리를 가질 수 있습니다 (예 : 답변이로드되고 저장되는 방식). 그래서 하나의 뷰 모델에서 그것을 혼합하는 것은 좋지 않습니다 ... –

답변

1

이것은 내가 내 프로젝트에서 끝낸 것입니다 (나는 무한 스크롤과 함께리스트 뷰를가집니다). 기본적으로, 저는 가상화의 일부를 직접했습니다.

DataTemplateSelector을 완전히 삭제했습니다. MyCustomContainer 간단한 UserControl을이다

<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 줄의 코드가 필요했습니다.