You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:35:22