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

时间:2017-03-14 03:46:12

标签: checkbox uwp styles multi-select listviewitem

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

body {
    margin: 0px;
    margin-bottom: 150px;
}

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

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

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

但是,如果我这样做,那么我得到异常“ListViewItemPresenter只能用作ListViewItem模板中的第一个子节点。”

是否有或多或少的简单方法?

- SJB

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

1 个答案:

答案 0 :(得分:4)

您必须修改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>

要完全控制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>
      </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
    <Rectangle x:Name="BorderBackground"
                IsHitTestVisible="False"
                Fill="{ThemeResource SystemControlHighlightListAccentLowBrush}"
                Opacity="0"
                Control.IsTemplateFocusTarget="True"/>
    <Grid x:Name="ContentPresenterGrid"
          Background="Transparent"
          Margin="0,0,0,0">
      <Grid.RenderTransform>
        <TranslateTransform x:Name="ContentPresenterTranslateTransform"/>
      </Grid.RenderTransform>
      <ContentPresenter x:Name="ContentPresenter"
                        ContentTransitions="{TemplateBinding ContentTransitions}"
                        ContentTemplate="{TemplateBinding ContentTemplate}"
                        Content="{TemplateBinding Content}"
                        HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                        VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                        Margin="{TemplateBinding Padding}"/>
    </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"
                Opacity="0"
                Text="Xg"
                Foreground="{x:Null}"
                Margin="{TemplateBinding Padding}"
                IsHitTestVisible="False"
                AutomationProperties.AccessibilityView="Raw"/>
    <Rectangle x:Name="PlaceholderRect"
                Visibility="Collapsed"
                Fill="{ThemeResource ListViewItemPlaceholderBackgroundThemeBrush}"/>
    <Rectangle x:Name="MultiArrangeOverlayBackground"
                IsHitTestVisible="False"
                Opacity="0"
                Fill="{ThemeResource ListViewItemDragBackgroundThemeBrush}"
                Grid.ColumnSpan="2"/>
    <Border x:Name="MultiSelectSquare"
            BorderBrush="{ThemeResource SystemControlForegroundBaseMediumHighBrush}"
            BorderThickness="2"
            Width="20"
            Height="20"
            Margin="12,0,0,0"
            VerticalAlignment="Center"
            HorizontalAlignment="Left"
            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"
                FontFamily="{ThemeResource SymbolThemeFontFamily}"
                Glyph="&#xE73E;"
                FontSize="16"
                Foreground="{ThemeResource SystemControlForegroundBaseMediumHighBrush}"
                Visibility="Collapsed"
                Opacity="0"/>
    </Border>
    <TextBlock x:Name="MultiArrangeOverlayText"
                Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.DragItemsCount}"
                Foreground="{ThemeResource ListViewItemDragForegroundThemeBrush}"
                FontFamily="{ThemeResource ContentControlThemeFontFamily}"
                FontSize="26.667"
                IsHitTestVisible="False"
                Opacity="0"
                TextWrapping="Wrap"
                TextTrimming="WordEllipsis"
                Margin="18,9,0,0"
                AutomationProperties.AccessibilityView="Raw"
                Grid.ColumnSpan="2"/>
          </Grid>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
</Style>

在那里你可以看到MultiSelectCheck图标,它负责复选框的外观,你可以尝试修改它和相关的视觉状态,以便在你的应用程序风格中看得更多。

请注意,在某些情况下,使用此扩展模板可能会损害ListView的性能。您应该阅读thisthis文章,以便更好地了解ListView的效果。