UWP 列表视图单元格分隔符

UWP list view cell separator

如标题所述,我正在尝试获取 ListView 的单元格分隔符。我找到了一种绘制分隔符的方法,但不幸的是,它导致列表视图项没有单元格悬停颜色和单元格选择颜色。

<Style x:Key="BorderedItem" TargetType="ListViewItem">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ListViewItem">
                <Border Name="Border" BorderBrush="LightGray" BorderThickness="0,0,0,1" Margin="4,0,4,0">
                    <ContentPresenter/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>

我还尝试 重新添加 highlight/selection 颜色。但问题是 ListViewItemPresenter 不能在 Border 内。将 Border 放在 ListViewItemPresenter 中会隐藏整个单元格。所以无论如何要有电池分隔符而不会丢失 highlight/hover/selection 颜色?

当你为ListViewItem设置样式时,不要忘记VisualStateGroups设置,它用于控制高亮、悬停、选择和其他效果。此外,您不需要为单元格分隔符添加边框控件。只需将 BorderBrush 设置为 ContentPresenterGrid 即可。更新样式如下:

 <Style x:Key="BorderedItem" TargetType="ListViewItem">
     <Setter Property="Template">
         <Setter.Value>
             <ControlTemplate TargetType="ListViewItem">
                 <Grid
                     x:Name="ContentBorder"
                     Background="{TemplateBinding Background}"
                     BorderBrush="{TemplateBinding BorderBrush}"
                     BorderThickness="{TemplateBinding BorderThickness}">
                     <Rectangle
                         x:Name="BorderBackground"
                         Fill="{ThemeResource SystemControlHighlightListAccentLowBrush}"
                         Opacity="0"
                         Control.IsTemplateFocusTarget="True"
                         IsHitTestVisible="False" />
                     <Grid
                         x:Name="ContentPresenterGrid"
                         Margin="0,0,0,0"
                         Background="Transparent"
                         BorderBrush="LightGray"
                         BorderThickness="0,0,0,1">
                         <Grid.RenderTransform>
                             <TranslateTransform x:Name="ContentPresenterTranslateTransform" />
                         </Grid.RenderTransform>
                         <ContentPresenter
                             x:Name="ContentPresenter"
                             Margin="{TemplateBinding Padding}"
                             HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                             VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                             Content="{TemplateBinding Content}"
                             ContentTemplate="{TemplateBinding ContentTemplate}"
                             ContentTransitions="{TemplateBinding ContentTransitions}" />
                     </Grid>
                     <!--
                         The 'Xg' text simulates the amount of space one line of text will occupy.
                         In the DataPlaceholder state, the Content is not loaded yet so we
                         approximate the size of the item using placeholder text.
                     -->
                     <TextBlock
                         x:Name="PlaceholderTextBlock"
                         Margin="{TemplateBinding Padding}"
                         Foreground="{x:Null}"
                         Opacity="0"
                         AutomationProperties.AccessibilityView="Raw"
                         IsHitTestVisible="False"
                         Text="Xg" />
                     <Rectangle
                         x:Name="PlaceholderRect"
                         Fill="{ThemeResource ListViewItemPlaceholderBackgroundThemeBrush}"
                         Visibility="Collapsed" />
                     <Rectangle
                         x:Name="MultiArrangeOverlayBackground"
                         Grid.ColumnSpan="2"
                         Fill="{ThemeResource ListViewItemDragBackgroundThemeBrush}"
                         Opacity="0"
                         IsHitTestVisible="False" />
                     <Border
                         x:Name="MultiSelectSquare"
                         Width="20"
                         Height="20"
                         Margin="12,0,0,0"
                         HorizontalAlignment="Left"
                         VerticalAlignment="Center"
                         BorderBrush="{ThemeResource SystemControlForegroundBaseMediumHighBrush}"
                         BorderThickness="2"
                         Visibility="Collapsed">
                         <Border.Clip>
                             <RectangleGeometry Rect="0,0,20,20">
                                 <RectangleGeometry.Transform>
                                     <TranslateTransform x:Name="MultiSelectClipTransform" />
                                 </RectangleGeometry.Transform>
                             </RectangleGeometry>
                         </Border.Clip>
                         <Border.RenderTransform>
                             <TranslateTransform x:Name="MultiSelectCheckBoxTransform" />
                         </Border.RenderTransform>
                         <FontIcon
                             x:Name="MultiSelectCheck"
                             Foreground="{ThemeResource SystemControlForegroundBaseMediumHighBrush}"
                             Opacity="0"
                             FontFamily="{ThemeResource SymbolThemeFontFamily}"
                             FontSize="16"
                             Glyph="&#xE73E;"
                             Visibility="Collapsed" />
                     </Border>
                     <TextBlock
                         x:Name="MultiArrangeOverlayText"
                         Grid.ColumnSpan="2"
                         Margin="18,9,0,0"
                         Foreground="{ThemeResource ListViewItemDragForegroundThemeBrush}"
                         Opacity="0"
                         FontFamily="{ThemeResource ContentControlThemeFontFamily}"
                         FontSize="26.667"
                         AutomationProperties.AccessibilityView="Raw"
                         IsHitTestVisible="False"
                         Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.DragItemsCount}"
                         TextTrimming="WordEllipsis"
                         TextWrapping="Wrap" />
                     <VisualStateManager.VisualStateGroups>
                         <VisualStateGroup x:Name="CommonStates">
                             <VisualState x:Name="Normal">
                                 <Storyboard>
                                     <PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter" />
                                 </Storyboard>
                             </VisualState>
                             <VisualState x:Name="PointerOver">
                                 <Storyboard>
                                     <DoubleAnimation
                                         Duration="0"
                                         Storyboard.TargetName="BorderBackground"
                                         Storyboard.TargetProperty="Opacity"
                                         To="1" />
                                     <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderBackground" Storyboard.TargetProperty="Fill">
                                         <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightListLowBrush}" />
                                     </ObjectAnimationUsingKeyFrames>
                                     <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
                                         <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}" />
                                     </ObjectAnimationUsingKeyFrames>
                                     <PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter" />
                                 </Storyboard>
                             </VisualState>
                             <VisualState x:Name="Pressed">
                                 <Storyboard>
                                     <DoubleAnimation
                                         Duration="0"
                                         Storyboard.TargetName="BorderBackground"
                                         Storyboard.TargetProperty="Opacity"
                                         To="1" />
                                     <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderBackground" Storyboard.TargetProperty="Fill">
                                         <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightListMediumBrush}" />
                                     </ObjectAnimationUsingKeyFrames>
                                     <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
                                         <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}" />
                                     </ObjectAnimationUsingKeyFrames>
                                     <PointerDownThemeAnimation TargetName="ContentPresenter" />
                                 </Storyboard>
                             </VisualState>
                             <VisualState x:Name="Selected">
                                 <Storyboard>
                                     <DoubleAnimation
                                         Duration="0:0:0"
                                         Storyboard.TargetName="MultiSelectCheck"
                                         Storyboard.TargetProperty="Opacity"
                                         To="1" />
                                     <DoubleAnimation
                                         Duration="0"
                                         Storyboard.TargetName="BorderBackground"
                                         Storyboard.TargetProperty="Opacity"
                                         To="1" />
                                     <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderBackground" Storyboard.TargetProperty="Fill">
                                         <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightListAccentLowBrush}" />
                                     </ObjectAnimationUsingKeyFrames>
                                     <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
                                         <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}" />
                                     </ObjectAnimationUsingKeyFrames>
                                     <PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter" />
                                 </Storyboard>
                             </VisualState>
                             <VisualState x:Name="PointerOverSelected">
                                 <Storyboard>
                                     <DoubleAnimation
                                         Duration="0:0:0"
                                         Storyboard.TargetName="MultiSelectCheck"
                                         Storyboard.TargetProperty="Opacity"
                                         To="1" />
                                     <DoubleAnimation
                                         Duration="0"
                                         Storyboard.TargetName="BorderBackground"
                                         Storyboard.TargetProperty="Opacity"
                                         To="1" />
                                     <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderBackground" Storyboard.TargetProperty="Fill">
                                         <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightListAccentMediumBrush}" />
                                     </ObjectAnimationUsingKeyFrames>
                                     <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
                                         <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}" />
                                     </ObjectAnimationUsingKeyFrames>
                                     <PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter" />
                                 </Storyboard>
                             </VisualState>
                             <VisualState x:Name="PressedSelected">
                                 <Storyboard>
                                     <DoubleAnimation
                                         Duration="0:0:0"
                                         Storyboard.TargetName="MultiSelectCheck"
                                         Storyboard.TargetProperty="Opacity"
                                         To="1" />
                                     <DoubleAnimation
                                         Duration="0"
                                         Storyboard.TargetName="BorderBackground"
                                         Storyboard.TargetProperty="Opacity"
                                         To="1" />
                                     <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderBackground" Storyboard.TargetProperty="Fill">
                                         <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightListAccentHighBrush}" />
                                     </ObjectAnimationUsingKeyFrames>
                                     <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
                                         <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}" />
                                     </ObjectAnimationUsingKeyFrames>
                                     <PointerDownThemeAnimation TargetName="ContentPresenter" />
                                 </Storyboard>
                             </VisualState>
                         </VisualStateGroup>
                         <VisualStateGroup x:Name="DisabledStates">
                             <VisualState x:Name="Enabled" />
                             <VisualState x:Name="Disabled">
                                 <Storyboard>
                                     <DoubleAnimation
                                         Duration="0"
                                         Storyboard.TargetName="ContentBorder"
                                         Storyboard.TargetProperty="Opacity"
                                         To="{ThemeResource ListViewItemDisabledThemeOpacity}" />
                                 </Storyboard>
                             </VisualState>
                         </VisualStateGroup>
                         <VisualStateGroup x:Name="MultiSelectStates">
                             <VisualState x:Name="MultiSelectDisabled">
                                 <Storyboard>
                                     <DoubleAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectCheckBoxTransform" Storyboard.TargetProperty="X">
                                         <EasingDoubleKeyFrame KeyTime="0:0:0" Value="0" />
                                         <SplineDoubleKeyFrame
                                             KeySpline="0.1,0.9,0.2,1"
                                             KeyTime="0:0:0.333"
                                             Value="-32" />
                                     </DoubleAnimationUsingKeyFrames>
                                     <DoubleAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectClipTransform" Storyboard.TargetProperty="X">
                                         <EasingDoubleKeyFrame KeyTime="0:0:0" Value="0" />
                                         <SplineDoubleKeyFrame
                                             KeySpline="0.1,0.9,0.2,1"
                                             KeyTime="0:0:0.333"
                                             Value="32" />
                                     </DoubleAnimationUsingKeyFrames>
                                     <DoubleAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenterTranslateTransform" Storyboard.TargetProperty="X">
                                         <EasingDoubleKeyFrame KeyTime="0:0:0" Value="32" />
                                         <SplineDoubleKeyFrame
                                             KeySpline="0.1,0.9,0.2,1"
                                             KeyTime="0:0:0.333"
                                             Value="0" />
                                     </DoubleAnimationUsingKeyFrames>
                                     <ObjectAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectSquare" Storyboard.TargetProperty="Visibility">
                                         <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
                                         <DiscreteObjectKeyFrame KeyTime="0:0:0.333" Value="Collapsed" />
                                     </ObjectAnimationUsingKeyFrames>
                                 </Storyboard>
                             </VisualState>
                             <VisualState x:Name="MultiSelectEnabled">
                                 <Storyboard>
                                     <DoubleAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectCheckBoxTransform" Storyboard.TargetProperty="X">
                                         <EasingDoubleKeyFrame KeyTime="0:0:0" Value="-32" />
                                         <SplineDoubleKeyFrame
                                             KeySpline="0.1,0.9,0.2,1"
                                             KeyTime="0:0:0.333"
                                             Value="0" />
                                     </DoubleAnimationUsingKeyFrames>
                                     <DoubleAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectClipTransform" Storyboard.TargetProperty="X">
                                         <EasingDoubleKeyFrame KeyTime="0:0:0" Value="32" />
                                         <SplineDoubleKeyFrame
                                             KeySpline="0.1,0.9,0.2,1"
                                             KeyTime="0:0:0.333"
                                             Value="0" />
                                     </DoubleAnimationUsingKeyFrames>
                                     <DoubleAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenterTranslateTransform" Storyboard.TargetProperty="X">
                                         <EasingDoubleKeyFrame KeyTime="0:0:0" Value="-32" />
                                         <SplineDoubleKeyFrame
                                             KeySpline="0.1,0.9,0.2,1"
                                             KeyTime="0:0:0.333"
                                             Value="0" />
                                     </DoubleAnimationUsingKeyFrames>
                                     <ObjectAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectSquare" Storyboard.TargetProperty="Visibility">
                                         <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
                                     </ObjectAnimationUsingKeyFrames>
                                     <ObjectAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectCheck" Storyboard.TargetProperty="Visibility">
                                         <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
                                     </ObjectAnimationUsingKeyFrames>
                                     <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenterGrid" Storyboard.TargetProperty="Margin">
                                         <DiscreteObjectKeyFrame KeyTime="0" Value="32,0,0,0" />
                                     </ObjectAnimationUsingKeyFrames>
                                 </Storyboard>
                             </VisualState>
                         </VisualStateGroup>
                         <VisualStateGroup x:Name="DataVirtualizationStates">
                             <VisualState x:Name="DataAvailable" />
                             <VisualState x:Name="DataPlaceholder">
                                 <Storyboard>
                                     <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PlaceholderTextBlock" Storyboard.TargetProperty="Visibility">
                                         <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
                                     </ObjectAnimationUsingKeyFrames>
                                     <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PlaceholderRect" Storyboard.TargetProperty="Visibility">
                                         <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
                                     </ObjectAnimationUsingKeyFrames>
                                 </Storyboard>
                             </VisualState>
                         </VisualStateGroup>
                         <VisualStateGroup x:Name="ReorderHintStates">
                             <VisualState x:Name="NoReorderHint" />
                             <VisualState x:Name="BottomReorderHint">
                                 <Storyboard>
                                     <DragOverThemeAnimation
                                         Direction="Bottom"
                                         ToOffset="{ThemeResource ListViewItemReorderHintThemeOffset}"
                                         TargetName="ContentBorder" />
                                 </Storyboard>
                             </VisualState>
                             <VisualState x:Name="TopReorderHint">
                                 <Storyboard>
                                     <DragOverThemeAnimation
                                         Direction="Top"
                                         ToOffset="{ThemeResource ListViewItemReorderHintThemeOffset}"
                                         TargetName="ContentBorder" />
                                 </Storyboard>
                             </VisualState>
                             <VisualState x:Name="RightReorderHint">
                                 <Storyboard>
                                     <DragOverThemeAnimation
                                         Direction="Right"
                                         ToOffset="{ThemeResource ListViewItemReorderHintThemeOffset}"
                                         TargetName="ContentBorder" />
                                 </Storyboard>
                             </VisualState>
                             <VisualState x:Name="LeftReorderHint">
                                 <Storyboard>
                                     <DragOverThemeAnimation
                                         Direction="Left"
                                         ToOffset="{ThemeResource ListViewItemReorderHintThemeOffset}"
                                         TargetName="ContentBorder" />
                                 </Storyboard>
                             </VisualState>
                             <VisualStateGroup.Transitions>
                                 <VisualTransition GeneratedDuration="0:0:0.2" To="NoReorderHint" />
                             </VisualStateGroup.Transitions>
                         </VisualStateGroup>
                         <VisualStateGroup x:Name="DragStates">
                             <VisualState x:Name="NotDragging" />
                             <VisualState x:Name="Dragging">
                                 <Storyboard>
                                     <DoubleAnimation
                                         Duration="0"
                                         Storyboard.TargetName="ContentBorder"
                                         Storyboard.TargetProperty="Opacity"
                                         To="{ThemeResource ListViewItemDragThemeOpacity}" />
                                     <DragItemThemeAnimation TargetName="ContentBorder" />
                                 </Storyboard>
                             </VisualState>
                             <VisualState x:Name="DraggingTarget">
                                 <Storyboard>
                                     <DropTargetItemThemeAnimation TargetName="ContentBorder" />
                                 </Storyboard>
                             </VisualState>
                             <VisualState x:Name="MultipleDraggingPrimary">
                                 <Storyboard>
                                     <!--
                                         These two Opacity animations are required - the FadeInThemeAnimations
                                         on the same elements animate an internal Opacity.
                                     -->
                                     <DoubleAnimation
                                         Duration="0"
                                         Storyboard.TargetName="MultiArrangeOverlayBackground"
                                         Storyboard.TargetProperty="Opacity"
                                         To="1" />
                                     <DoubleAnimation
                                         Duration="0"
                                         Storyboard.TargetName="MultiArrangeOverlayText"
                                         Storyboard.TargetProperty="Opacity"
                                         To="1" />
                                     <DoubleAnimation
                                         Duration="0"
                                         Storyboard.TargetName="ContentBorder"
                                         Storyboard.TargetProperty="Opacity"
                                         To="{ThemeResource ListViewItemDragThemeOpacity}" />
                                     <FadeInThemeAnimation TargetName="MultiArrangeOverlayBackground" />
                                     <FadeInThemeAnimation TargetName="MultiArrangeOverlayText" />
                                     <DragItemThemeAnimation TargetName="ContentBorder" />
                                 </Storyboard>
                             </VisualState>
                             <VisualState x:Name="MultipleDraggingSecondary">
                                 <Storyboard>
                                     <FadeOutThemeAnimation TargetName="ContentBorder" />
                                 </Storyboard>
                             </VisualState>
                             <VisualState x:Name="DraggedPlaceholder">
                                 <Storyboard>
                                     <FadeOutThemeAnimation TargetName="ContentBorder" />
                                 </Storyboard>
                             </VisualState>
                             <VisualStateGroup.Transitions>
                                 <VisualTransition GeneratedDuration="0:0:0.2" To="NotDragging" />
                             </VisualStateGroup.Transitions>
                         </VisualStateGroup>
                     </VisualStateManager.VisualStateGroups>
                 </Grid>
             </ControlTemplate>
         </Setter.Value>
     </Setter>
 </Style>

结果:

更多详情请参考ListViewItem styles and templates. And I have a demo about the ListView cell separator you may reference:https://github.com/sunteenwu/CDesign