如何在 UWP 中的多选 ListView 中设置复选框样式

sjb*_*sjb 0 checkbox styles listviewitem multi-select uwp

在 UWP 中,我使用带有项目模板的多选 ListView,如下所示:

    <ListView 
        ItemsSource="{x:Bind ItemsSource, Mode=OneWay}" 
        ItemTemplate="{x:Bind LineTemplate, Mode=OneWay}"
        SelectionMode="Multiple"
        >
    </ListView>
Run Code Online (Sandbox Code Playgroud)

问题是UWP添加的复选框的样式。在我程序的其余部分中,我有自己的复选框样式,而 ListView 中的样式不匹配。

我看不到任何设置复选框样式的方法,也看不到 ListViewItem 模板中 ListViewItemPresenter 的任何代码。

也许我可以设置 IsMultiSelectCheckBoxEnabled="False",然后在 ListViewItem 中包含我自己的 CheckBox。我看到了如何在 ListViewItem 样式中将 CheckBox 添加到模板中:我可以将它放在 ListViewItemPresenter 之前(例如使用水平 StackPanel)。然后我可以绑定 IsChecked="{TemplateBinding IsSelected}"。

但是,如果我这样做,则会出现异常“ListViewItemPresenter 只能用作 ListViewItem 模板中的第一个子项”。

有没有或多或少简单的方法来做到这一点?

--sjb

PS 显然 ListViewItemPresenter 非常特别......我的印象是它内置了很多优化,不应该只是扔掉。

And*_*min 5

你必须修改ItemContainerStyle. 尽管如果您尝试使用 Visual Studio 工具对其进行修改,您将只能访问它的有限版本,如下所示:

<Style x:Key="ListViewItemStyle1" TargetType="ListViewItem">
        <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
        <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
        <Setter Property="TabNavigation" Value="Local"/>
        <Setter Property="IsHoldingEnabled" Value="True"/>
        <Setter Property="Padding" Value="12,0,12,0"/>
        <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
        <Setter Property="VerticalContentAlignment" Value="Center"/>
        <Setter Property="MinWidth" Value="{ThemeResource ListViewItemMinWidth}"/>
        <Setter Property="MinHeight" Value="{ThemeResource ListViewItemMinHeight}"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListViewItem">
                    <ListViewItemPresenter CheckBrush="{ThemeResource SystemControlForegroundBaseMediumHighBrush}" ContentMargin="{TemplateBinding Padding}" CheckMode="Inline" ContentTransitions="{TemplateBinding ContentTransitions}" CheckBoxBrush="{ThemeResource SystemControlForegroundBaseMediumHighBrush}" DragForeground="{ThemeResource ListViewItemDragForegroundThemeBrush}" DragOpacity="{ThemeResource ListViewItemDragThemeOpacity}" DragBackground="{ThemeResource ListViewItemDragBackgroundThemeBrush}" DisabledOpacity="{ThemeResource ListViewItemDisabledThemeOpacity}" FocusBorderBrush="{ThemeResource SystemControlForegroundAltHighBrush}" FocusSecondaryBorderBrush="{ThemeResource SystemControlForegroundBaseHighBrush}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" PointerOverForeground="{ThemeResource SystemControlHighlightAltBaseHighBrush}" PressedBackground="{ThemeResource SystemControlHighlightListMediumBrush}" PlaceholderBackground="{ThemeResource ListViewItemPlaceholderBackgroundThemeBrush}" PointerOverBackground="{ThemeResource SystemControlHighlightListLowBrush}" ReorderHintOffset="{ThemeResource ListViewItemReorderHintThemeOffset}" SelectedPressedBackground="{ThemeResource SystemControlHighlightListAccentHighBrush}" SelectionCheckMarkVisualEnabled="True" SelectedForeground="{ThemeResource SystemControlHighlightAltBaseHighBrush}" SelectedPointerOverBackground="{ThemeResource SystemControlHighlightListAccentMediumBrush}" SelectedBackground="{ThemeResource SystemControlHighlightListAccentLowBrush}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
Run Code Online (Sandbox Code Playgroud)

要完全控制 listviewitem 容器,您需要使用另一个模板,如下所示:

<!-- Style for Windows.UI.Xaml.Controls.ListViewItem -->
<Style TargetType="ListViewItem" x:Key="ListViewItemExpanded">
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}" />
<Setter Property="TabNavigation" Value="Local"/>
<Setter Property="IsHoldingEnabled" Value="True"/>
<Setter Property="Padding" Value="12,0,12,0"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="MinWidth" Value="{ThemeResource ListViewItemMinWidth}"/>
<Setter Property="MinHeight" Value="{ThemeResource ListViewItemMinHeight}"/>
<Setter Property="UseSystemFocusVisuals" Value="True" />
<Setter Property="Template">
  <Setter.Value>
    <ControlTemplate TargetType="ListViewItem">
      <Grid x:Name="ContentBorder"
          Background="{TemplateBinding Background}"
          BorderBrush="{TemplateBinding BorderBrush}"
          BorderThickness="{TemplateBinding BorderThickness}">
    <VisualStateManager.VisualStateGroups>
      <VisualStateGroup x:Name="CommonStates">
        <VisualState x:Name="Normal">
          <Storyboard>
            <PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter" />
          </Storyboard>
        </VisualState>
        <VisualState x:Name="PointerOver">
          <Storyboard>
            <DoubleAnimation Storyboard.TargetName="BorderBackground"
                             Storyboard.TargetProperty="Opacity"
                             Duration="0"
                             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 Storyboard.TargetName="BorderBackground"
                             Storyboard.TargetProperty="Opacity"
                             Duration="0"
                             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 Storyboard.TargetName="MultiSelectCheck"
                             Storyboard.TargetProperty="Opacity"
                             Duration="0:0:0"
                             To="1"/>
            <DoubleAnimation Storyboard.TargetName="BorderBackground"
                             Storyboard.TargetProperty="Opacity"
                             Duration="0"
                             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 Storyboard.TargetName="MultiSelectCheck"
                             Storyboard.TargetProperty="Opacity"
                             Duration="0:0:0"
                             To="1"/>
            <DoubleAnimation Storyboard.TargetName="BorderBackground"
                             Storyboard.TargetProperty="Opacity"
                             Duration="0"
                             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 Storyboard.TargetName="MultiSelectCheck"
                             Storyboard.TargetProperty="Opacity"
                             Duration="0:0:0"
                             To="1"/>
            <DoubleAnimation Storyboard.TargetName="BorderBackground"
                             Storyboard.TargetProperty="Opacity"
                             Duration="0"
                             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 Storyboard.TargetName="ContentBorder"
                             Storyboard.TargetProperty="Opacity"
                             Duration="0"
                             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 KeyTime="0:0:0.333" Value="-32" KeySpline="0.1,0.9,0.2,1"/>
            </DoubleAnimationUsingKeyFrames>
            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectClipTransform"
                                           Storyboard.TargetProperty="X">
              <EasingDoubleKeyFrame KeyTime="0:0:0" Value="0"/>
              <SplineDoubleKeyFrame KeyTime="0:0:0.333" Value="32" KeySpline="0.1,0.9,0.2,1"/>
            </DoubleAnimationUsingKeyFrames>
            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenterTranslateTransform"
                                           Storyboard.TargetProperty="X">
              <EasingDoubleKeyFrame KeyTime="0:0:0" Value="32"/>
              <SplineDoubleKeyFrame KeyTime="0:0:0.333" Value="0" KeySpline="0.1,0.9,0.2,1"/>
            </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 KeyTime="0:0:0.333" Value="0" KeySpline="0.1,0.9,0.2,1"/>
            </DoubleAnimationUsingKeyFrames>
            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectClipTransform"
                                           Storyboard.TargetProperty="X">
              <EasingDoubleKeyFrame KeyTime="0:0:0" Value="32"/>
              <SplineDoubleKeyFrame KeyTime="0:0:0.333" Value="0" KeySpline="0.1,0.9,0.2,1"/>
            </DoubleAnimationUsingKeyFrames>
            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenterTranslateTransform"
                                           Storyboard.TargetProperty="X">
              <EasingDoubleKeyFrame KeyTime="0:0:0" Value="-32"/>
              <SplineDoubleKeyFrame KeyTime="0:0:0.333" Value="0" KeySpline="0.1,0.9,0.2,1"/>
            </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 TargetName="ContentBorder" ToOffset="{ThemeResource ListViewItemReorderHintThemeOffset}" Direction="Bottom" />
          </Storyboard>
        </VisualState>
        <VisualState x:Name="TopReorderHint">
          <Storyboard>
            <DragOverThemeAnimation TargetName="ContentBorder" ToOffset="{ThemeResource ListViewItemReorderHintThemeOffset}" Direction="Top" />
          </Storyboard>
        </VisualState>
        <VisualState x:Name="RightReorderHint">
          <Storyboard>
            <DragOverThemeAnimation TargetName="ContentBorder" ToOffset="{ThemeResource ListViewItemReorderHintThemeOffset}" Direction="Right" />
          </Storyboard>
        </VisualState>
        <VisualState x:Name="LeftReorderHint">
          <Storyboard>
            <DragOverThemeAnimation TargetName="ContentBorder" ToOffset="{ThemeResource ListViewItemReorderHintThemeOffset}" Direction="Left" />
          </Storyboard>
        </VisualState>
        <VisualStateGroup.Transitions>
          <VisualTransition To="NoReorderHint" GeneratedDuration="0:0:0.2"/>
        </VisualStateGroup.Transitions>
      </VisualStateGroup>
      <VisualStateGroup x:Name="DragStates">
        <VisualState x:Name="NotDragging" />
        <VisualState x:Name="Dragging">
          <Storyboard>
            <DoubleAnimation Storyboard.TargetName="ContentBorder"
                             Storyboard.TargetProperty="Opacity"
                             Duration="0"
                             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 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" />
          </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 To="NotDragging" GeneratedDuration="0:0:0.2"/>
        </VisualStateGroup.Transitions