如何无需重写模板/派生类,动态设置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
相关产品推荐
相关产品推荐

