为什么 VisualState Selected 在 listviewitem 中不起作用?

Why VisualState Selected no work in listviewitem?

这是XAML:

<ListView Grid.Column="1" Grid.Row="1" Name="TaskListView" HorizontalContentAlignment="Center">
                        <ListView.ItemContainerStyle>
                            <Style TargetType="ListViewItem">
                                <Setter Property="HorizontalContentAlignment"  Value="Stretch"></Setter>                               
                            </Style>
                        </ListView.ItemContainerStyle>
                        <ListView.ItemTemplate>
                            <DataTemplate>
                                <Grid Margin="0,10,0,0" Background="#00FF0000" AllowFocusOnInteraction="False">
                                    <VisualStateManager.VisualStateGroups>
                                        <VisualStateGroup x:Name="CommonStates">
                                            <VisualState x:Name="Normal">
                                                <VisualState.Setters>
                                                    <Setter Value="#2c567b" Target="InnerBorder.BorderBrush"/>
                                                </VisualState.Setters>
                                            </VisualState>
                                            <VisualState x:Name="Selected">
                                                <VisualState.Setters>
                                                    <Setter Value="White" Target="InnerBorder.BorderBrush"/>
                                                    <Setter Value="White" Target="InnerBorder.Background"/>
                                                    <Setter Value="#db4662" Target="InnerTextBlock.Foreground"/>
                                                    <Setter Value="#db4662" Target="InnerRectangle.Fill"/>
                                                </VisualState.Setters>
                                            </VisualState>
                                        </VisualStateGroup>
                                    </VisualStateManager.VisualStateGroups>
                                    <Border BorderThickness="4" BorderBrush="#2c567b" Grid.ColumnSpan="2" Name="InnerBorder"></Border>
                                    <Grid Padding="20,20,0,20" Name="InnerG">
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="auto"></ColumnDefinition>
                                            <ColumnDefinition Width="*"></ColumnDefinition>
                                        </Grid.ColumnDefinitions>
                                        <Rectangle Fill="#30fff8" Margin="10" Name="InnerRectangle"></Rectangle>
                                        <TextBlock Grid.Column="1" Foreground="#30fff8" Margin="20,0,0,0" Text="{Binding ProductName}" VerticalAlignment="Center"></TextBlock>
                                    </Grid>
                                </Grid>
                            </DataTemplate>
                        </ListView.ItemTemplate>
                    </ListView>

当我刚刚创建一个 listviewitem 的控件模板时,它 works.But 在我 add/edit 它到 DataTemplate 之后,它失败了。

很抱歉,我是 UWP 的初学者,几乎找不到同时创建 controltemplate/add 到 listviewitem 的数据模板的示例。

你能帮帮我吗?谢谢。

原因是当你这样定义VisualStates时,它们属于内部Grid元素,实际上没有定义任何Selected状态。当您检查 documentation 时,您可以看到 Selected 状态是在 ListViewItem 控件上定义的,它充当实际 "items" 的包装器(从数据模板生成的内容).因此,您应该为 ListViewItem 创建自定义样式并将其分配给 ListView.ItemContainerStyle.

您可以通过多种方式修改样式,但最简单的是将 ListView 放在页面上,在 Designer文档大纲,然后选择编辑其他模板编辑生成的项目容器,最后编辑一个复制...。这将生成默认 ListViewItemStyle 的副本,您可以根据自己的喜好自由修改。

@Martin 已经解释了这个问题的解决方案,但是正如你提到的你是初学者,我想指出一些可能对你有帮助的事情。

请参阅 this MSDN 文档,其中包含为 ListView 定义的样式和模板。

ListView样式中,您会发现如下所示的选定视觉状态,您可以根据需要修改该状态。

<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>

首先,您可以按照@Martin 的回答创建 ListView 的 ItemContainerStyle,然后更改 ListViewItem 的 ControlTemplate,因此 PointerOverNormal VisualState 将如下所示:

 <VisualState x:Name="Normal">
     <VisualState.Setters>
         <Setter Target="Root.(RevealBrush.State)" Value="PointerOver"/>
         <Setter Target="Root.Foreground" Value="#30fff8"/>
         <Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ListViewItemRevealBorderBrushPointerOver}"/>
     </VisualState.Setters>
 </VisualState>
 <VisualState x:Name="Selected"/>
 <VisualState x:Name="PointerOver">
     <VisualState.Setters>
         <Setter Target="Root.(RevealBrush.State)" Value="PointerOver"/>
         <Setter Target="Root.Foreground" Value="Red"/>
         <Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ListViewItemRevealBorderBrushPointerOver}"/>
     </VisualState.Setters>
 </VisualState>

我们更改 PointerOverNormal VisualState 中的 Root.Foreground请删除您的 DataTemplate 中您的 TextBlock 的 Foreground="#30fff8" 代码作为@David 的评论。

另一方面,您也可以从 C:\Program Files (x86)\Windows Kits\DesignTime\CommonConfiguration\Neutral\UAP\{SDK 版本}\Generic\generic 获取默认的 ListViewItem 样式。 xaml 文件。您可以将 x:Key="ListViewItemExpanded" 的样式复制到您的 Page.Resource 中并删除 x:Key="ListViewItemExpanded",然后此样式将应用于所有 ListViewItems你的页面。然后你可以找到 NormalPointerOver Visualstate 根据需要进行一些更改。另请注意,删除 DataTemplate.

中 TextBlock 的 Foreground="#30fff8" 代码

---更新---

这里我把第一个场景的xaml代码全部贴在这里,你可以试试。

<Page.Resources>
        <Style x:Key="ListViewItemRevealStyle" TargetType="ListViewItem">
            <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
            <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
            <Setter Property="Background" Value="{ThemeResource ListViewItemBackground}"/>
            <Setter Property="Foreground" Value="{ThemeResource ListViewItemForeground}"/>
            <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="AllowDrop" Value="False"/>
            <Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}"/>
            <Setter Property="FocusVisualMargin" Value="0"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListViewItem">
                        <ListViewItemPresenter x:Name="Root" CheckBrush="{ThemeResource ListViewItemCheckBrush}" ContentMargin="{TemplateBinding Padding}" CheckBoxBrush="{ThemeResource ListViewItemCheckBoxBrush}" ContentTransitions="{TemplateBinding ContentTransitions}" CheckMode="{ThemeResource ListViewItemCheckMode}" DragOpacity="{ThemeResource ListViewItemDragThemeOpacity}" DisabledOpacity="{ThemeResource ListViewItemDisabledThemeOpacity}" DragBackground="{ThemeResource ListViewItemDragBackground}" DragForeground="{ThemeResource ListViewItemDragForeground}" FocusBorderBrush="{ThemeResource ListViewItemFocusBorderBrush}" FocusVisualMargin="{TemplateBinding FocusVisualMargin}" FocusSecondaryBorderBrush="{ThemeResource ListViewItemFocusSecondaryBorderBrush}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Control.IsTemplateFocusTarget="True" PressedBackground="{ThemeResource ListViewItemBackgroundPressed}" PlaceholderBackground="{ThemeResource ListViewItemPlaceholderBackground}" PointerOverForeground="{ThemeResource ListViewItemForegroundPointerOver}" PointerOverBackground="{ThemeResource ListViewItemBackgroundPointerOver}"  ReorderHintOffset="{ThemeResource ListViewItemReorderHintThemeOffset}" SelectedForeground="{ThemeResource ListViewItemForegroundSelected}" SelectionCheckMarkVisualEnabled="{ThemeResource ListViewItemSelectionCheckMarkVisualEnabled}" SelectedBackground="{ThemeResource ListViewItemBackgroundSelected}" SelectedPressedBackground="{ThemeResource ListViewItemBackgroundSelectedPressed}" SelectedPointerOverBackground="{ThemeResource ListViewItemBackgroundSelectedPointerOver}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}">
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Normal">
                                        <VisualState.Setters>
                                            <Setter Target="Root.(RevealBrush.State)" Value="PointerOver"/>
                                            <Setter Target="Root.Foreground" Value="#30fff8"/>
                                            <Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ListViewItemRevealBorderBrushPointerOver}"/>
                                        </VisualState.Setters>
                                    </VisualState>
                                    <VisualState x:Name="Selected"/>
                                    <VisualState x:Name="PointerOver">
                                        <VisualState.Setters>
                                            <Setter Target="Root.(RevealBrush.State)" Value="PointerOver"/>
                                            <Setter Target="Root.Foreground" Value="Red"/>
                                            <Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ListViewItemRevealBorderBrushPointerOver}"/>
                                        </VisualState.Setters>
                                    </VisualState>
                                    <VisualState x:Name="PointerOverSelected">
                                        <VisualState.Setters>
                                            <Setter Target="Root.(RevealBrush.State)" Value="PointerOver"/>
                                            <Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ListViewItemRevealBorderBrushPointerOver}"/>
                                        </VisualState.Setters>
                                    </VisualState>
                                    <VisualState x:Name="PointerOverPressed">
                                        <VisualState.Setters>
                                            <Setter Target="Root.(RevealBrush.State)" Value="Pressed"/>
                                            <Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ListViewItemRevealBorderBrushPressed}"/>
                                        </VisualState.Setters>
                                    </VisualState>
                                    <VisualState x:Name="Pressed">
                                        <VisualState.Setters>
                                            <Setter Target="Root.(RevealBrush.State)" Value="Pressed"/>
                                            <Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ListViewItemRevealBorderBrushPressed}"/>
                                        </VisualState.Setters>
                                    </VisualState>
                                    <VisualState x:Name="PressedSelected">
                                        <VisualState.Setters>
                                            <Setter Target="Root.(RevealBrush.State)" Value="Pressed"/>
                                            <Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ListViewItemRevealBorderBrushPressed}"/>
                                        </VisualState.Setters>
                                    </VisualState>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="DisabledStates">
                                    <VisualState x:Name="Enabled"/>
                                    <VisualState x:Name="Disabled">
                                        <VisualState.Setters>
                                            <Setter Target="Root.RevealBorderThickness" Value="0"/>
                                        </VisualState.Setters>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                        </ListViewItemPresenter>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <Style x:Key="ListViewItemContainerStyle1" BasedOn="{StaticResource ListViewItemRevealStyle}" TargetType="ListViewItem"/>
    </Page.Resources>

<Grid>
        <ListView ItemContainerStyle="{StaticResource ListViewItemContainerStyle1}" Name="TaskListView" HorizontalContentAlignment="Center">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Grid Margin="0,10,0,0" AllowFocusOnInteraction="False" >
                        <Border BorderThickness="4" BorderBrush="#2c567b" Grid.ColumnSpan="2" Name="InnerBorder"></Border>
                        <Grid Padding="20,20,0,20" Name="InnerG">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="auto"></ColumnDefinition>
                                <ColumnDefinition Width="*"></ColumnDefinition>
                            </Grid.ColumnDefinitions>
                            <Rectangle Fill="#30fff8" Margin="10" Name="InnerRectangle"></Rectangle>
                            <TextBlock Grid.Column="1" Margin="20,0,0,0" Text="{Binding ProductName}" VerticalAlignment="Center"></TextBlock>
                            <!-- You can add other controls and bind data-->
                        </Grid>
                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>