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

WinUI3自定义NavigationViewItem选中样式:悬停/按下时保持强调色

解决WinUI3 NavigationViewItem选中时全状态强调色样式问题

你当前的样式只设置了NavigationViewItem的默认状态属性,而悬停、按下这类交互状态的外观是由控件模板(ControlTemplate)内的VisualStateManager控制的,所以需要扩展样式,覆盖对应交互状态的视觉属性。

步骤1:修改XAML中的Style,覆盖控件模板的视觉状态

基于WinUI3默认的NavigationViewItem样式,修改sx1样式,添加控件模板并调整选中相关的交互状态(比如SelectedPointerOver、SelectedPressed)的背景和前景:

<NavigationView.Resources>
    <Style TargetType="NavigationViewItem" x:Key="sx1">
        <!-- 基础状态属性 -->
        <Setter Property="Background" Value="{ThemeResource AccentTextFillColorPrimaryBrush}"/>
        <Setter Property="Foreground" Value="{ThemeResource TextOnAccentFillColorPrimaryBrush}"/>
        <!-- 重写控件模板,修改交互状态 -->
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="NavigationViewItem">
                    <Grid x:Name="LayoutRoot" Background="{TemplateBinding Background}" Control.IsTemplateFocusTarget="True">
                        <!-- 视觉状态管理 -->
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="PointerStates">
                                <!-- 默认选中状态 -->
                                <VisualState x:Name="Selected">
                                    <VisualState.Setters>
                                        <Setter Target="LayoutRoot.Background" Value="{ThemeResource AccentTextFillColorPrimaryBrush}"/>
                                        <Setter Target="ContentPresenter.Foreground" Value="{ThemeResource TextOnAccentFillColorPrimaryBrush}"/>
                                    </VisualState.Setters>
                                </VisualState>
                                <!-- 选中+鼠标悬停状态 -->
                                <VisualState x:Name="SelectedPointerOver">
                                    <VisualState.Setters>
                                        <Setter Target="LayoutRoot.Background" Value="{ThemeResource AccentTextFillColorPrimaryBrush}"/>
                                        <Setter Target="ContentPresenter.Foreground" Value="{ThemeResource TextOnAccentFillColorPrimaryBrush}"/>
                                    </VisualState.Setters>
                                </VisualState>
                                <!-- 选中+鼠标按下状态 -->
                                <VisualState x:Name="SelectedPressed">
                                    <VisualState.Setters>
                                        <Setter Target="LayoutRoot.Background" Value="{ThemeResource AccentTextFillColorPrimaryBrush}"/>
                                        <Setter Target="ContentPresenter.Foreground" Value="{ThemeResource TextOnAccentFillColorPrimaryBrush}"/>
                                    </VisualState.Setters>
                                </VisualState>
                                <!-- 非选中状态(按需保留默认样式) -->
                                <VisualState x:Name="Normal"/>
                                <VisualState x:Name="PointerOver">
                                    <VisualState.Setters>
                                        <Setter Target="LayoutRoot.Background" Value="{ThemeResource NavigationViewItemBackgroundPointerOver}"/>
                                        <Setter Target="ContentPresenter.Foreground" Value="{ThemeResource NavigationViewItemForegroundPointerOver}"/>
                                    </VisualState.Setters>
                                </VisualState>
                                <VisualState x:Name="Pressed">
                                    <VisualState.Setters>
                                        <Setter Target="LayoutRoot.Background" Value="{ThemeResource NavigationViewItemBackgroundPressed}"/>
                                        <Setter Target="ContentPresenter.Foreground" Value="{ThemeResource NavigationViewItemForegroundPressed}"/>
                                    </VisualState.Setters>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <!-- 控件内容容器(保留默认布局结构) -->
                        <ContentPresenter x:Name="ContentPresenter"
                                          Content="{TemplateBinding Content}"
                                          ContentTemplate="{TemplateBinding ContentTemplate}"
                                          Foreground="{TemplateBinding Foreground}"
                                          HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</NavigationView.Resources>

提示:实际开发中建议通过Blend工具提取WinUI3默认的NavigationViewItem完整模板,再修改对应VisualState属性,避免丢失控件的默认布局和功能。

步骤2:确保C++/WinRT代码正确应用样式

你的现有代码中st0_def赋值为nullptr,若要应用默认样式可直接省略Style设置;应用sx1样式的代码无需修改,只需确保navView是正确的NavigationView实例:

winrt::Microsoft::UI::Xaml::Style st1_def = navView.Resources().Lookup(winrt::box_value(L"sx1")).as<winrt::Microsoft::UI::Xaml::Style>();
// 为item2应用自定义样式
navView.FindName(L"item2").as<winrt::Microsoft::UI::Xaml::Controls::NavigationViewItem>().Style(st1_def);

关键说明

  • 必须为所有选中相关的交互状态(Selected、SelectedPointerOver、SelectedPressed)设置相同的强调色属性,才能保证任意交互状态下样式一致。
  • 使用系统主题资源(如AccentTextFillColorPrimaryBrush、TextOnAccentFillColorPrimaryBrush)可让样式自动跟随系统主题变化。

内容的提问来源于stack exchange,提问作者Michael Chourdakis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 04:35:10