如何修改UWP中SplitView面板的选中项样式与颜色?
解决UWP汉堡菜单选中样式自定义问题
嘿,我帮你搞定这个UWP汉堡菜单的选中样式需求!不管是想改成侧边小矩形,还是自定义选中颜色,都可以通过自定义样式和VisualState来实现,下面给你具体的方案和代码示例:
方案1:自定义选中颜色(替换系统强调色)
如果只是想修改选中项的颜色,有两种灵活的实现方式:
方式A:全局替换(所有ListView生效)
在App.xaml的资源里直接覆盖系统默认的选中状态资源,这样所有ListView的选中样式都会统一修改:
<Application.Resources> <!-- 替换选中背景色 --> <SolidColorBrush x:Key="ListViewItemSelectedBackgroundThemeBrush" Color="#E8F0FE"/> <!-- 可选:修改选中时的文字颜色 --> <SolidColorBrush x:Key="ListViewItemSelectedForegroundThemeBrush" Color="#FF1A73E8"/> </Application.Resources>
方式B:仅给汉堡菜单的ListView单独设置
这种方式不会影响其他ListView的样式,更适合局部自定义。先在页面资源里定义专属的ListViewItem样式:
<Page.Resources> <Style x:Key="CustomMenuListItemStyle" TargetType="ListViewItem"> <Setter Property="Padding" Value="0"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ListViewItem"> <Grid x:Name="RootGrid"> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="SelectionStates"> <VisualState x:Name="Unselected"/> <VisualState x:Name="Selected"> <Storyboard> <!-- 设置你想要的选中背景色 --> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Background"> <DiscreteObjectKeyFrame KeyTime="0" Value="#E8F0FE"/> </ObjectAnimationUsingKeyFrames> <!-- 可选:设置选中时的文字颜色 --> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground"> <DiscreteObjectKeyFrame KeyTime="0" Value="#FF1A73E8"/> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="SelectedUnfocused"> <!-- 非焦点状态下保持相同的选中样式 --> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Background"> <DiscreteObjectKeyFrame KeyTime="0" Value="#E8F0FE"/> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <ContentPresenter x:Name="ContentPresenter" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> </Page.Resources>
然后把这个样式应用到汉堡菜单的ListView上:
<SplitView Name="menu" IsPaneOpen="True" PanePlacement="Left"> <SplitView.Pane> <ListView x:Name="MenuListView" SelectionMode="Single" ItemContainerStyle="{StaticResource CustomMenuListItemStyle}"> <!-- 你的菜单项内容 --> </ListView> </SplitView.Pane> <!-- 主内容区 --> </SplitView>
方案2:添加侧边小矩形作为选中指示器
如果想把选中样式改成侧边的小矩形,我们可以在菜单项的DataTemplate里加一个默认隐藏的矩形,然后通过VisualState在选中时显示它:
第一步:定义带指示器的菜单项模板
<SplitView.Pane> <ListView x:Name="MenuListView" SelectionMode="Single" ItemContainerStyle="{StaticResource MenuItemWithIndicatorStyle}"> <ListView.ItemTemplate> <DataTemplate> <Grid Height="48" Margin="0,4"> <!-- 侧边选中指示器,默认隐藏 --> <Rectangle x:Name="SelectionIndicator" Width="4" Fill="#FF1A73E8" <!-- 自定义指示器颜色 --> HorizontalAlignment="Left" Visibility="Collapsed"/> <!-- 菜单项内容:图标+文字 --> <StackPanel Orientation="Horizontal" Margin="16,0"> <SymbolIcon Symbol="{Binding Icon}" Margin="0,0,12,0"/> <TextBlock Text="{Binding Label}" VerticalAlignment="Center"/> </StackPanel> </Grid> </DataTemplate> </ListView.ItemTemplate> <!-- 示例菜单项 --> <ListView.Items> <local:MenuItem Icon="Home" Label="首页"/> <local:MenuItem Icon="Settings" Label="设置"/> <local:MenuItem Icon="Help" Label="帮助"/> </ListView.Items> </ListView> </SplitView.Pane>
第二步:自定义样式控制指示器显示
在页面资源里定义样式,核心是在选中状态下触发矩形的显示:
<Page.Resources> <Style x:Key="MenuItemWithIndicatorStyle" TargetType="ListViewItem"> <Setter Property="Padding" Value="0"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ListViewItem"> <Grid x:Name="RootGrid"> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CommonStates"> <VisualState x:Name="Normal"/> <VisualState x:Name="PointerOver"> <!-- 可选:设置鼠标悬停时的背景色 --> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Background"> <DiscreteObjectKeyFrame KeyTime="0" Value="#F0F0F0"/> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> </VisualStateGroup> <VisualStateGroup x:Name="SelectionStates"> <VisualState x:Name="Unselected"/> <VisualState x:Name="Selected"> <Storyboard> <!-- 显示侧边指示器 --> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="SelectionIndicator" Storyboard.TargetProperty="Visibility"> <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="SelectedUnfocused"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="SelectionIndicator" Storyboard.TargetProperty="Visibility"> <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <ContentPresenter Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> </Page.Resources>
第三步:简单的MenuItem数据模型(绑定用)
如果你的菜单项是通过数据绑定实现的,需要定义一个基础模型类:
public class MenuItem { public Symbol Icon { get; set; } public string Label { get; set; } }
额外说明
- 如果你的汉堡菜单用的是
NavigationView而不是SplitView+ListView,原理完全一致:只需要自定义NavigationViewItem的样式,或者在它的ContentTemplate里添加指示器,再通过VisualState控制显示即可。 - 你可以根据需求自由调整颜色、矩形宽度、边距,甚至给指示器添加淡入淡出的动画过渡效果,让交互更流畅。
试试上面的代码,应该能完美实现你想要的效果!
内容的提问来源于stack exchange,提问作者user8171157
相关产品推荐
相关产品推荐

