C# UWP NavigationView:一个NavigationViewItem下的两个视图

C# UWP NavigationView:一个NavigationViewItem下的两个视图,c#,uwp,C#,Uwp,我正在尝试创建一个NavigationViewItem,它根据条件导航到两个不同的视图 UWP应用程序是使用Windows Template Studio创建的,并且已经具有NavigationView和在页面之间导航的默认功能。我想让应用程序检查条件,然后如果用户单击NavigationViewItem,则导航到一个或另一个视图。此外,应用程序还应在单个NavigationViewItem上保留彩色线条,指示它所打开的视图 这就是我的NavigationView当前的样子。我想合并SetTim

我正在尝试创建一个
NavigationViewItem
,它根据条件导航到两个不同的视图

UWP应用程序是使用Windows Template Studio创建的,并且已经具有
NavigationView
和在页面之间导航的默认功能。我想让应用程序检查条件,然后如果用户单击
NavigationViewItem
,则导航到一个或另一个视图。此外,应用程序还应在单个
NavigationViewItem
上保留彩色线条,指示它所打开的视图

这就是我的
NavigationView
当前的样子。我想合并
SetTimer
WatchTimer
视图。不幸的是,我不知道底层代码是如何工作的,因为它都是自动生成的,我并不真正理解它

<winui:NavigationView.MenuItems>
    <winui:NavigationViewItem x:Uid="Shell_SetTimer" helpers:NavHelper.NavigateTo="views:SetTimerPage" />
    <winui:NavigationViewItem x:Uid="Shell_WatchTimer" helpers:NavHelper.NavigateTo="views:WatchTimerPage" />
    <winui:NavigationViewItem x:Uid="Shell_History" helpers:NavHelper.NavigateTo="views:HistoryPage" />
</winui:NavigationView.MenuItems>

这就是背后的代码:

using System;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;

using ShutdownTimer.Helpers;
using ShutdownTimer.Services;

using Windows.System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Navigation;

using WinUI = Microsoft.UI.Xaml.Controls;

namespace ShutdownTimer.Views
{
    public sealed partial class ShellPage : Page, INotifyPropertyChanged
    {
        private readonly KeyboardAccelerator _altLeftKeyboardAccelerator = BuildKeyboardAccelerator(VirtualKey.Left, VirtualKeyModifiers.Menu);
        private readonly KeyboardAccelerator _backKeyboardAccelerator = BuildKeyboardAccelerator(VirtualKey.GoBack);

        private bool _isBackEnabled;
        private WinUI.NavigationViewItem _selected;

        public bool IsBackEnabled
        {
            get { return _isBackEnabled; }
            set { Set(ref _isBackEnabled, value); }
        }

        public WinUI.NavigationViewItem Selected
        {
            get { return _selected; }
            set { Set(ref _selected, value); }
        }

        public ShellPage()
        {
            InitializeComponent();
            DataContext = this;
            Initialize();
        }

        private void Initialize()
        {
            NavigationService.Frame = shellFrame;
            NavigationService.NavigationFailed += Frame_NavigationFailed;
            NavigationService.Navigated += Frame_Navigated;
            navigationView.BackRequested += OnBackRequested;
        }

        private async void OnLoaded(object sender, RoutedEventArgs e)
        {
            // Keyboard accelerators are added here to avoid showing 'Alt + left' tooltip on the page.
            // More info on tracking issue https://github.com/Microsoft/microsoft-ui-xaml/issues/8
            KeyboardAccelerators.Add(_altLeftKeyboardAccelerator);
            KeyboardAccelerators.Add(_backKeyboardAccelerator);
            await Task.CompletedTask;
        }

        private void Frame_NavigationFailed(object sender, NavigationFailedEventArgs e)
        {
            throw e.Exception;
        }

        private void Frame_Navigated(object sender, NavigationEventArgs e)
        {
            IsBackEnabled = NavigationService.CanGoBack;
            if (e.SourcePageType == typeof(SettingsPage))
            {
                Selected = navigationView.SettingsItem as WinUI.NavigationViewItem;
                return;
            }

            Selected = navigationView.MenuItems
                            .OfType<WinUI.NavigationViewItem>()
                            .FirstOrDefault(menuItem => IsMenuItemForPageType(menuItem, e.SourcePageType));
        }

        private bool IsMenuItemForPageType(WinUI.NavigationViewItem menuItem, Type sourcePageType)
        {
            var pageType = menuItem.GetValue(NavHelper.NavigateToProperty) as Type;
            return pageType == sourcePageType;
        }

        private void OnItemInvoked(WinUI.NavigationView sender, WinUI.NavigationViewItemInvokedEventArgs args)
        {
            if (args.IsSettingsInvoked)
            {
                NavigationService.Navigate(typeof(SettingsPage));
                return;
            }

            var item = navigationView.MenuItems
                            .OfType<WinUI.NavigationViewItem>()
                            .First(menuItem => (string)menuItem.Content == (string)args.InvokedItem);
            var pageType = item.GetValue(NavHelper.NavigateToProperty) as Type;
            NavigationService.Navigate(pageType);
        }

        private void OnBackRequested(WinUI.NavigationView sender, WinUI.NavigationViewBackRequestedEventArgs args)
        {
            NavigationService.GoBack();
        }

        private static KeyboardAccelerator BuildKeyboardAccelerator(VirtualKey key, VirtualKeyModifiers? modifiers = null)
        {
            var keyboardAccelerator = new KeyboardAccelerator() { Key = key };
            if (modifiers.HasValue)
            {
                keyboardAccelerator.Modifiers = modifiers.Value;
            }

            keyboardAccelerator.Invoked += OnKeyboardAcceleratorInvoked;
            return keyboardAccelerator;
        }

        private static void OnKeyboardAcceleratorInvoked(KeyboardAccelerator sender, KeyboardAcceleratorInvokedEventArgs args)
        {
            var result = NavigationService.GoBack();
            args.Handled = result;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void Set<T>(ref T storage, T value, [CallerMemberName]string propertyName = null)
        {
            if (Equals(storage, value))
            {
                return;
            }

            storage = value;
            OnPropertyChanged(propertyName);
        }

        private void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
使用系统;
使用系统组件模型;
使用System.Linq;
使用System.Runtime.CompilerServices;
使用System.Threading.Tasks;
使用关机计时器。助手;
使用ShutdownTimer.Services;
使用Windows.System;
使用Windows.UI.Xaml;
使用Windows.UI.Xaml.Controls;
使用Windows.UI.Xaml.Input;
使用Windows.UI.Xaml.Navigation;
使用WinUI=Microsoft.UI.Xaml.Controls;
命名空间关闭计时器.Views
{
公共密封部分类ShellPage:第页,INotifyPropertyChanged
{
私有只读键盘加速器_altLeftKeyboardAccelerator=BuildKeyboardAccelerator(VirtualKey.Left,VirtualKeyModifiers.Menu);
私有只读键盘加速器_backKeyboardAccelerator=BuildKeyboardAccelerator(VirtualKey.GoBack);
私用bool\u已启用;
私有WinUI.NavigationViewItem _已选中;
公共bool已启用
{
获取{return\u isBackEnabled;}
set{set(ref_isBackEnabled,value);}
}
已选择公共WinUI.NavigationViewItem
{
获取{return\u selected;}
集合{set(ref_selected,value);}
}
公共网页()
{
初始化组件();
DataContext=this;
初始化();
}
私有void初始化()
{
NavigationService.Frame=shellFrame;
NavigationService.NavigationFailed+=框架_NavigationFailed;
NavigationService.Navigated+=已导航的帧;
navigationView.BackRequested+=OnBackRequested;
}
已加载专用异步void(对象发送方,RoutedEventArgs e)
{
//此处添加了键盘加速器,以避免在页面上显示“Alt+left”工具提示。
//有关跟踪问题的更多信息https://github.com/Microsoft/microsoft-ui-xaml/issues/8
键盘加速器。添加(\u AltLeftKeyboardAccelerators);
键盘加速器。添加(_backKeyboardAccelerator);
等待任务。完成任务;
}
私有无效帧_NavigationFailed(对象发送方,NavigationFailedEventArgs e)
{
抛出e.异常;
}
已导航的专用无效帧(对象发送方、导航目标)
{
IsBackEnabled=NavigationService.CanGoBack;
如果(例如SourcePageType==typeof(设置页面))
{
Selected=navigationView.SettingsItem为WinUI.NavigationViewItem;
返回;
}
选定项=navigationView.MenuItems
第()类
.FirstOrDefault(menuItem=>IsMenuItemForPageType(menuItem,e.SourcePageType));
}
私有bool IsMenuItemForPageType(WinUI.NavigationViewItem菜单项,类型sourcePageType)
{
var pageType=menuItem.GetValue(NavHelper.NavigateToProperty)作为类型;
返回pageType==sourcePageType;
}
私有voked(WinUI.NavigationView发送方,WinUI.NavigationViewItemInvokedEventArgs)
{
if(args.issettings已调用)
{
导航服务。导航(类型(设置页面));
返回;
}
var item=navigationView.MenuItems
第()类
.First(menuItem=>(string)menuItem.Content==(string)args.InvokedItem);
var pageType=item.GetValue(NavHelper.NavigateToProperty)作为类型;
导航服务。导航(页面类型);
}
请求返回时的私有void(WinUI.NavigationView发送方,WinUI.NavigationViewBackRequestedEventArgs参数)
{
NavigationService.GoBack();
}
专用静态键盘加速器BuildKeyboardAccelerator(VirtualKey,VirtualKeyModifiers?modifiers=null)
{
var keyboardAccelerator=newkeyboardAccelerator(){Key=Key};
if(修饰符.HasValue)
{
键盘加速器。修饰符=修饰符。值;
}
keyboardAccelerator.Invoked+=OnKeyboardAcceleratorInvoked;
返回键盘加速器;
}
KeyboardAcceleratorInvoked上的私有静态无效(KeyboardAcceleratorInvokedEventArgs键盘加速器发送器)
{
var result=NavigationService.GoBack();
args.Handled=结果;
}
公共事件属性更改事件处理程序属性更改;
私有无效集(引用T存储,T值,[CallerMemberName]字符串propertyName=null)
{
if(等于(存储、值))
{
返回;
}
储存=价值;
OnPropertyChanged(propertyName);
}
私有void OnPropertyChanged(字符串propertyName)=>PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(propertyName));
}
}
导航助手呢

using System;

using Microsoft.UI.Xaml.Controls;

using Windows.UI.Xaml;

namespace ShutdownTimer.Helpers
{
    public class NavHelper
    {
        // This helper class allows to specify the page that will be shown when you click on a NavigationViewItem
        //
        // Usage in xaml:
        // <winui:NavigationViewItem x:Uid="Shell_Main" Icon="Document" helpers:NavHelper.NavigateTo="views:MainPage" />
        //
        // Usage in code:
        // NavHelper.SetNavigateTo(navigationViewItem, typeof(MainPage));
        public static Type GetNavigateTo(NavigationViewItem item)
        {
            return (Type)item.GetValue(NavigateToProperty);
        }

        public static void SetNavigateTo(NavigationViewItem item, Type value)
        {
            item.SetValue(NavigateToProperty, value);
        }

        public static readonly DependencyProperty NavigateToProperty =
            DependencyProperty.RegisterAttached("NavigateTo", typeof(Type), typeof(NavHelper), new PropertyMetadata(null));
    }
}
使用系统;
使用Microsoft.UI.Xaml.Control