還是先上效果圖: 看完了上一篇UWP Composition API - GroupListView(一)的童鞋會問,這不是跟上一篇一樣的嗎??? 騙點擊的?? No,No,其實相對上一個有更簡單粗暴的方案,因為上篇是為了研究Composition API,所以含著淚都要做完(有沒有被騙的趕腳)。。 ...
還是先上效果圖:
看完了上一篇UWP Composition API - GroupListView(一)的童鞋會問,這不是跟上一篇一樣的嗎??? 騙點擊的??
No,No,其實相對上一個有更簡單粗暴的方案,因為上篇是為了研究Composition API,所以含著淚都要做完(有沒有被騙的趕腳)。。( ╯□╰ )
那是有沒有簡單點的方法呢?? 嗯,看到這篇,那答案肯定是Yes。
我再啰嗦下需求:
1.Group中的集合需要支持增量載入ISupportIncrementalLoading
2.支持UI Virtualization
這個簡單的方案就是改ListViewItem的模板,其實我在UWP VirtualizedVariableSizedGridView 支持可虛擬化可變大小Item的View(二)有講過ListViewItem有2套模板-官方地址
看一下我修改之後的模板:
<Style TargetType="local:GroupListViewItem" > <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" /> <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" /> <Setter Property="Background" Value="Transparent"/> <Setter Property="TabNavigation" Value="Local"/> <Setter Property="IsHoldingEnabled" Value="True"/> <Setter Property="Margin" Value="0,0,18,2"/> <Setter Property="HorizontalContentAlignment" Value="Left"/> <Setter Property="VerticalContentAlignment" Value="Top"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="local:GroupListViewItem"> <Border x:Name="OuterContainer"> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CommonStates"> <VisualState x:Name="Normal"/> <VisualState x:Name="PointerOver"> <Storyboard> <DoubleAnimation Storyboard.TargetName="PointerOverBorder" Storyboard.TargetProperty="Opacity" Duration="0" To="1" /> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="SelectionBackground" Storyboard.TargetProperty="Fill"> <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListViewItemSelectedPointerOverBackgroundThemeBrush}" /> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="SelectedBorder" Storyboard.TargetProperty="Stroke"> <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListViewItemSelectedPointerOverBorderThemeBrush}" /> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="SelectedEarmark" Storyboard.TargetProperty="Fill"> <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListViewItemSelectedPointerOverBackgroundThemeBrush}" /> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="Pressed"> <Storyboard> <PointerDownThemeAnimation TargetName="ContentContainer" /> </Storyboard> </VisualState> <VisualState x:Name="PointerOverPressed"> <Storyboard> <PointerDownThemeAnimation TargetName="ContentContainer" /> <DoubleAnimation Storyboard.TargetName="PointerOverBorder" Storyboard.TargetProperty="Opacity" Duration="0" To="1" /> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="SelectionBackground" Storyboard.TargetProperty="Fill"> <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListViewItemSelectedPointerOverBackgroundThemeBrush}" /> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="SelectedBorder" Storyboard.TargetProperty="Stroke"> <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListViewItemSelectedPointerOverBorderThemeBrush}" /> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="SelectedEarmark" Storyboard.TargetProperty="Fill"> <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListViewItemSelectedPointerOverBackgroundThemeBrush}" /> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="Disabled"> <Storyboard> <DoubleAnimation Storyboard.TargetName="contentPresenter" Storyboard.TargetProperty="Opacity" Duration="0" To="{ThemeResource ListViewItemDisabledThemeOpacity}" /> </Storyboard> </VisualState> </VisualStateGroup> <VisualStateGroup x:Name="FocusStates"> <VisualState x:Name="Focused"> <Storyboard> <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisual" /> </Storyboard> </VisualState> <VisualState x:Name="Unfocused"/> <VisualState x:Name="PointerFocused"/> </VisualStateGroup> <VisualStateGroup x:Name="SelectionHintStates"> <VisualState x:Name="VerticalSelectionHint"> <Storyboard> <SwipeHintThemeAnimation TargetName="SelectionBackground" ToVerticalOffset="15" ToHorizontalOffset="0" /> <SwipeHintThemeAnimation TargetName="ContentBorder" ToVerticalOffset="15" ToHorizontalOffset="0" /> <SwipeHintThemeAnimation TargetName="SelectedBorder" ToVerticalOffset="15" ToHorizontalOffset="0" /> <SwipeHintThemeAnimation TargetName="SelectedCheckMark" ToVerticalOffset="15" ToHorizontalOffset="0" /> <DoubleAnimationUsingKeyFrames Storyboard.TargetName="HintGlyph" Storyboard.TargetProperty="Opacity" Duration="0:0:0.500"> <DiscreteDoubleKeyFrame Value="0.5" KeyTime="0:0:0" /> <DiscreteDoubleKeyFrame Value="0" KeyTime="0:0:0.500" /> </DoubleAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="HorizontalSelectionHint"> <Storyboard> <SwipeHintThemeAnimation TargetName="SelectionBackground" ToHorizontalOffset="-23" ToVerticalOffset="0" /> <SwipeHintThemeAnimation TargetName="ContentBorder" ToHorizontalOffset="-23" ToVerticalOffset="0" /> <SwipeHintThemeAnimation TargetName="SelectedBorder" ToHorizontalOffset="-23" ToVerticalOffset="0" /> <SwipeHintThemeAnimation TargetName="SelectedCheckMark" ToHorizontalOffset="-23" ToVerticalOffset="0" /> <DoubleAnimationUsingKeyFrames Storyboard.TargetName="HintGlyph" Storyboard.TargetProperty="Opacity" Duration="0:0:0.500"> <DiscreteDoubleKeyFrame Value="0.5" KeyTime="0:0:0" /> <DiscreteDoubleKeyFrame Value="0" KeyTime="0:0:0.500" /> </DoubleAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="NoSelectionHint" /> <VisualStateGroup.Transitions> <VisualTransition To="NoSelectionHint" GeneratedDuration="0:0:0.65"/> </VisualStateGroup.Transitions> </VisualStateGroup> <VisualStateGroup x:Name="SelectionStates"> <VisualState x:Name="Unselecting"> <Storyboard> <DoubleAnimation Storyboard.TargetName="HintGlyphBorder" Storyboard.TargetProperty="Opacity" Duration="0" To="1" /> </Storyboard> </VisualState> <VisualState x:Name="Unselected"> <Storyboard> <DoubleAnimation Storyboard.TargetName="HintGlyphBorder" Storyboard.TargetProperty="Opacity" Duration="0" To="1" /> </Storyboard> </VisualState> <VisualState x:Name="UnselectedPointerOver"> <Storyboard> <DoubleAnimation Storyboard.TargetName="HintGlyphBorder" Storyboard.TargetProperty="Opacity" Duration="0" To="1" /> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="contentPresenter" Storyboard.TargetProperty="Foreground"> <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListViewItemSelectedForegroundThemeBrush}" /> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="UnselectedSwiping"> <Storyboard> <DoubleAnimation Storyboard.TargetName="SelectingGlyph" Storyboard.TargetProperty="Opacity" Duration="0" To="0.5" /> <DoubleAnimation Storyboard.TargetName="HintGlyphBorder" Storyboard.TargetProperty="Opacity" Duration="0" To="1" /> </Storyboard> </VisualState> <VisualState x:Name="Selecting"> <Storyboard> <DoubleAnimation Storyboard.TargetName="SelectionBackground" Storyboard.TargetProperty="Opacity" Duration="0" To="1" /> <DoubleAnimation Storyboard.TargetName="SelectedBorder" Storyboard.TargetProperty="Opacity" Duration="0" To="1" /> <DoubleAnimation Storyboard.TargetName="SelectingGlyph" Storyboard.TargetProperty="Opacity" Duration="0" To="1" /> <DoubleAnimation Storyboard.TargetName="HintGlyphBorder" Storyboard.TargetProperty="Opacity" Duration="0" To="1" /> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="contentPresenter" Storyboard.TargetProperty="Foreground"> <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListViewItemSelectedForegroundThemeBrush}" /> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="Selected"> <Storyboard> <DoubleAnimation Storyboard.TargetName="SelectionBackground" Storyboard.TargetProperty="Opacity" Duration="0" To="1" /> <DoubleAnimation Storyboard.TargetName="SelectedBorder" Storyboard.TargetProperty="Opacity" Duration="0" To="1" /> <DoubleAnimation Storyboard.TargetName="SelectedCheckMark" Storyboard.TargetProperty="Opacity" Duration="0" To="1" /> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="contentPresenter" Storyboard.TargetProperty="Foreground"> <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListViewItemSelectedForegroundThemeBrush}" /> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="SelectedSwiping"> <Storyboard> <DoubleAnimation Storyboard.TargetName="SelectionBackground" Storyboard.TargetProperty="Opacity" Duration="0" To="1" /> <DoubleAnimation Storyboard.TargetName="SelectedBorder" Storyboard.TargetProperty="Opacity" Duration="0" To="1" /> <DoubleAnimation Storyboard.TargetName="SelectedCheckMark" Storyboard.TargetProperty="Opacity" Duration="0" To="1" /> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="contentPresenter" Storyboard.TargetProperty="Foreground"> <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListViewItemSelectedForegroundThemeBrush}" /> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="SelectedUnfocused"> <Storyboard> <DoubleAnimation Storyboard.TargetName="SelectionBackground" Storyboard.TargetProperty="Opacity" Duration="0" To="1" /> <DoubleAnimation Storyboard.TargetName="SelectedBorder" Storyboard.TargetProperty="Opacity" Duration="0" To="1" /> <DoubleAnimation Storyboard.TargetName="SelectedCheckMark" Storyboard.TargetProperty="Opacity" Duration="0" To="1" /> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="contentPresenter" Storyboard.TargetProperty="Foreground"> <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ListViewItemSelectedForegroundThemeBrush}" /> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> </VisualStateGroup> <VisualStateGroup x:Name="DragStates"> <VisualState x:Name="NotDragging" /> <VisualState x:Name="Dragging"> <Storyboard> <DoubleAnimation Storyboard.TargetName="InnerDragContent" Storyboard.TargetProperty="Opacity" Duration="0" To="{ThemeResource ListViewItemDragThemeOpacity}" /> <DragItemThemeAnimation TargetName="InnerDragContent" /> <FadeOutThemeAnimation TargetName="SelectedCheckMarkOuter" /> <FadeOutThemeAnimation TargetName="SelectedBorder" /> </Storyboard> </VisualState> <VisualState x:Name="DraggingTarget"> <Storyboard> <DropTargetItemThemeAnimation TargetName="OuterContainer" /> </Storyboard> </VisualState> <VisualState x:Name="MultipleDraggingPrimary"> <Storyboard> <!-- These two Opacity animations are required - the FadeInThemeAnimations on the same elements animate an internal Opacity. --> <DoubleAnimation Storyboard.TargetName="MultiArrangeOverlayBackground" Storyboard.TargetProperty="Opacity" Duration="0" To="1" /> <DoubleAnimation Storyboard.TargetName="MultiArrangeOverlayText" Storyboard.TargetProperty="Opacity" Duration="0" To="1" /> <DoubleAnimation Storyboard.TargetName="ContentBorder" Storyboard.TargetProperty="Opacity" Duration="0" To="{ThemeResource ListViewItemDragThemeOpacity}" /> <FadeInThemeAnimation TargetName="MultiArrangeOverlayBackground" /> <FadeInThemeAnimation TargetName="MultiArrangeOverlayText" /> <DragItemThemeAnimation TargetName="ContentBorder" /> <FadeOutThemeAnimation TargetName="SelectionBackground" /> <FadeOutThemeAnimation TargetName="SelectedCheckMarkOuter" /> <FadeOutThemeAnimation TargetName="SelectedBorder" /> <FadeOutThemeAnimation TargetName="PointerOverBorder" /> </Storyboard> </VisualState> <VisualState x:Name="MultipleDraggingSecondary"> <Storyboard> <FadeOutThemeAnimation TargetName="ContentContainer" /> </Storyboard> </VisualState> <VisualStateGroup.Transitions> <VisualTransition To="NotDragging" GeneratedDuration="0:0:0.2"/> </VisualStateGroup.Transitions> </VisualStateGroup> <VisualStateGroup x:Name="ReorderHintStates"> <VisualState x:Name="NoReorderHint"/> <VisualState x:Name="BottomReorderHint"> <Storyboard> <DragOverThemeAnimation TargetName="ReorderHintContent" ToOffset="{ThemeResource ListViewItemReorderHintThemeOffset}" Direction="Bottom" /> </Storyboard> </VisualState> <VisualState x:Name="TopReorderHint"> <Storyboard> <DragOverThemeAnimation TargetName="ReorderHintContent" ToOffset="{ThemeResource ListViewItemReorderHintThemeOffset}" Direction="Top" /> </Storyboard> </VisualState> <VisualState x:Name="RightReorderHint"> <Storyboard> <DragOverThemeAnimation TargetName="ReorderHintContent" ToOffset="{ThemeResource ListViewItemReorderHintThemeOffset}" Direction="Right" /> </Storyboard> </VisualState> <VisualState x:Name="LeftReorderHint"> <Storyboard> <DragOverThemeAnimation TargetName="ReorderHintContent" ToOffset="{ThemeResource ListViewItemReorderHintThemeOffset}" Direction="Left" /> </Storyboard> </VisualState> <VisualStateGroup.Transitions> <VisualTransition To="NoReorderHint" GeneratedDuration="0:0:0.2"/> </VisualStateGroup.Transitions> </VisualStateGroup> <VisualStateGroup x:Name="DataVirtualizationStates"> <VisualState x:Name="DataAvailable"/> <VisualState x:Name="DataPlaceholder"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PlaceholderTextBlock" Storyboard.TargetProperty="Visibility" Duration="0"> <DiscreteObjectKeyFrame KeyTime="0"> <DiscreteObjectKeyFrame.Value> <Visibility>Visible</Visibility> </DiscreteObjectKeyFrame.Value> </DiscreteObjectKeyFrame> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PlaceholderRect" Storyboard.TargetProperty="Visibility" Duration="0"> <DiscreteObjectKeyFrame KeyTime="0"