UWP C++/WinRT 如何实现悬停/选中状态下ListViewItem的圆角
实现ListViewItem圆角高亮的可行方案
问题根因
你当前实现效果不符合预期的核心原因有两个:
- XAML语法挂载错误:原代码中ListView使用了自闭合标签,后续的Resources、ItemContainerStyle、ItemTemplate全部写在标签外部,这些属性根本没有关联到ListView实例上,自然不会生效。
- 内置高亮层层级问题:就算语法正确,ListViewItem的悬停、选中状态高亮是由其原生ControlTemplate内置的状态渲染层实现的,这个层默认是直角矩形,位于ItemTemplate内容的外层,仅修改ItemTemplate内部的Border圆角,无法覆盖这个内置直角高亮层的渲染边界。
完整修正实现
直接替换原代码为以下可运行的XAML配置即可:
<ListView x:Name="ObjectList" ItemsSource="{x:Bind ObjectViewModel.Objects}" SelectionChanged="ListViewButtonClick" MaxWidth="{StaticResource ColumnMaximumWidth}" VerticalAlignment="Center" HorizontalContentAlignment="Stretch" ScrollViewer.HorizontalScrollBarVisibility="Disabled" SelectionMode="Single"> <ListView.Resources> <!-- 覆盖全状态的默认高亮颜色,避免系统主题色透出直角效果 --> <SolidColorBrush x:Key="ListViewItemBackground" Color="Transparent" /> <SolidColorBrush x:Key="ListViewItemBackgroundPointerOver" Color="#33228B22" /> <SolidColorBrush x:Key="ListViewItemBackgroundPressed" Color="#55228B22" /> <SolidColorBrush x:Key="ListViewItemBackgroundSelected" Color="Green" /> <SolidColorBrush x:Key="ListViewItemBackgroundSelectedPointerOver" Color="Green" /> <SolidColorBrush x:Key="ListViewItemBackgroundSelectedPressed" Color="DarkGreen" /> </ListView.Resources> <ListView.ItemContainerStyle> <Style TargetType="ListViewItem"> <Setter Property="Margin" Value="0,0,0,30" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ListViewItem"> <!-- 替换原内置直角容器为圆角Border,承载所有状态的高亮渲染 --> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="5" UseLayoutRounding="True"> <ContentPresenter Padding="{TemplateBinding Padding}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> </ListView.ItemContainerStyle> <ListView.ItemTemplate> <DataTemplate x:DataType="local:ObjectModel"> <Border BorderBrush="Red" BorderThickness="3" CornerRadius="5"> <Grid MinHeight="66" CornerRadius="5"> <Grid.ColumnDefinitions> <ColumnDefinition Width="auto" /> <ColumnDefinition /> </Grid.ColumnDefinitions> <FontIcon FontSize="17" Glyph="" Style="{StaticResource FontIconStyle1}" /> <TextBlock Grid.Column="1" Style="{StaticResource AddBluetoothLabelTextStyle}" Text="{x:Bind ObjectName, Mode=OneWay}" /> </Grid> </Border> </DataTemplate> </ListView.ItemTemplate> </ListView>
关键改动说明
- 所有附属属性全部移入ListView标签内部,解决自闭合标签导致的属性挂载失效问题
- 重写ListViewItem的ControlTemplate,将原本的直角高亮容器替换为带指定圆角的Border,所有状态切换(悬停、按下、选中)的高亮都会严格沿着圆角边界渲染,不会出现直角漏出的问题
- 补全全场景的颜色资源配置,完全覆盖系统默认主题的高亮色,避免默认样式透出
- 统一内外层容器的圆角半径,避免边框和高亮层出现圆角错位
注意事项
如果运行时发现圆角被父容器裁切,可给ListView挂载的ScrollViewer添加配置:ScrollViewer.IsVerticalRailEnabled="True" ClipToBounds="False"
内容的提问来源于stack exchange,提问作者Sudheer Kumar
相关产品推荐
相关产品推荐

