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

如何无需重写模板/派生类,动态设置NavigationViewItem选中状态背景色?

动态设置NavigationViewItem选中状态背景色的简便方案

不需要重写控件模板或派生自定义控件,有几种简便的实现方式:

1. 直接动态覆盖Item的资源字典

NavigationViewItem的选中/选中悬停状态背景色是通过主题资源键定义的(NavigationViewItemSelectedBackground、NavigationViewItemSelectedPointerOverBackground),你可以在导航切换时,给当前选中的NavigationViewItem直接设置这两个资源的值,其优先级会高于全局主题资源。

示例代码:

// 导航切换时的处理逻辑
private void OnNavigationViewSelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
{
    if (args.SelectedItem is NavigationViewItem selectedItem && args.SelectedItemContainer is FrameworkElement container)
    {
        // 获取当前目标页面的背景色(根据你的页面结构自行实现)
        Brush targetPageBrush = GetCurrentPageBackgroundColor();
        
        // 覆盖当前选中Item的状态背景资源
        selectedItem.Resources["NavigationViewItemSelectedBackground"] = targetPageBrush;
        selectedItem.Resources["NavigationViewItemSelectedPointerOverBackground"] = targetPageBrush;
        
        // 可选:恢复之前选中Item的资源(如果需要)
        if (_previousSelectedItem != null)
        {
            _previousSelectedItem.Resources.Remove("NavigationViewItemSelectedBackground");
            _previousSelectedItem.Resources.Remove("NavigationViewItemSelectedPointerOverBackground");
        }
        _previousSelectedItem = selectedItem;
    }
}

2. 使用附加属性实现绑定式更新

创建一个附加属性,让NavigationViewItem可以直接绑定页面的背景色,自动同步状态背景。这种方式更贴合XAML的绑定逻辑,无需手动在导航事件里处理。

示例代码:

public static class NavigationViewItemHelpers
{
    public static readonly DependencyProperty MatchingPageBackgroundProperty =
        DependencyProperty.RegisterAttached(
            "MatchingPageBackground",
            typeof(Brush),
            typeof(NavigationViewItemHelpers),
            new PropertyMetadata(null, OnMatchingPageBackgroundChanged));

    public static Brush GetMatchingPageBackground(DependencyObject obj)
    {
        return (Brush)obj.GetValue(MatchingPageBackgroundProperty);
    }

    public static void SetMatchingPageBackground(DependencyObject obj, Brush value)
    {
        obj.SetValue(MatchingPageBackgroundProperty, value);
    }

    private static void OnMatchingPageBackgroundChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is NavigationViewItem item && e.NewValue is Brush newBrush)
        {
            // 绑定状态背景资源到附加属性的值
            item.Resources["NavigationViewItemSelectedBackground"] = newBrush;
            item.Resources["NavigationViewItemSelectedPointerOverBackground"] = newBrush;
        }
    }
}

在XAML中使用:

<NavigationViewItem 
    Content="首页"
    local:NavigationViewItemHelpers.MatchingPageBackground="{Binding HomePageBackground}" />

3. 监听VisualState变更直接修改背景

如果不想依赖资源键,可以监听NavigationViewItem的VisualStateChanged事件,在状态切换到Selected或SelectedPointerOver时直接设置背景色。

示例代码:

private void NavigationViewItem_VisualStateChanged(object sender, VisualStateChangedEventArgs e)
{
    if (sender is not NavigationViewItem item) return;
    
    Brush targetBrush = GetCurrentPageBackgroundColor();
    // 进入选中/选中悬停状态时设置背景
    if (e.NewState.Name is "Selected" or "SelectedPointerOver")
    {
        item.Background = targetBrush;
    }
    // 离开状态时可选择恢复默认背景
    else if (e.OldState.Name is "Selected" or "SelectedPointerOver")
    {
        item.ClearValue(Control.BackgroundProperty);
    }
}

注意:这种方式可能会和默认模板的动画过渡有冲突,推荐优先使用资源覆盖的方案。

内容的提问来源于stack exchange,提问作者sjb-sjb

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 09:53:34