上节课我们完成了,显示左侧栏,左侧栏有一个Frame,然后打开主窗体的适合,默认这个Frame显示一个默认的空白页面。但是我们现在点击左侧栏的菜单项,还不能打开其他的页面,本节课我们来完成这个功能,点击左侧栏不同的菜单,然后打开不同的页面(Page)。
最终效果

修改主窗体的菜单项
修改MainWindow.xaml
<NavigationView x:Name="NavView" PaneDisplayMode="Left" SelectionChanged="OnNavViewSelectionChanged">
<NavigationView.MenuItems>
<NavigationViewItem Content="Dashboard" Tag="DashboardPage" Icon="Home"/>
<NavigationViewItem Content="Analytics" Tag="AnalyticsPage" Icon="Account"/>
<NavigationViewItem Content="Play" Tag="PlayPage" Icon="Play"/>
</NavigationView.MenuItems>
<Frame x:Name="MainFrame"/>
</NavigationView>Code language: HTML, XML (xml)
主要变更:
- NavigationView 中增加一个事件,选择变更事件:SelectionChanged=”OnNavViewSelectionChanged”,当切换不同的菜单项触发
- 增加和修改了几个菜单项的,<NavigationViewItem Content=”Play” Tag=”PlayPage” Icon=”Play”/> 注意,Content是菜单名,Tag的字符串是页面名,Icon是图标,Winui内置的
增加几个空白页面DashboardPage、AnalyticsPage、PlayPage
每个页面的Grid中增加一个TextBlock, 然后设置不同的文本描述,用来区别不同页面。
<Grid>
<TextBlock Text="Dashboard Page" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="24"/>
</Grid>Code language: HTML, XML (xml)
<Grid>
<TextBlock Text="Analytics Page" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="24"/>
</Grid>Code language: HTML, XML (xml)
<Grid>
<TextBlock Text="Play Page" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="24"/>
</Grid>Code language: HTML, XML (xml)
实现切换函数
光标放到xaml的OnNavViewSelectionChanged这个事件函数上面,按住F12,然后vs会自动创建这个事件函数。分别在.h中创建函数声明,但是没有实现,然后在.cpp中创建函数实现,默认是跳到.cpp中,读者可以不知道.h也会创建。

如下则是XXXX.xaml.cpp 实现部分。
void winrt::AppWinui::implementation::MainWindow::OnNavViewSelectionChanged(winrt::Microsoft::UI::Xaml::Controls::NavigationView const& sender,
winrt::Microsoft::UI::Xaml::Controls::NavigationViewSelectionChangedEventArgs const& args)
{
// 获取选中的菜单项
auto selectedItem = args.SelectedItem().as<NavigationViewItem>();
if (!selectedItem) return;
// 取出 Tag 字符串
hstring tag = unbox_value<hstring>(selectedItem.Tag());
winrt::Windows::UI::Xaml::Interop::TypeName targetPage;
// 根据 Tag 匹配页面类型
if (tag == L"DashboardPage")
{
targetPage = xaml_typename<AppWinui::DashboardPage>();
}
else if (tag == L"AnalyticsPage")
{
targetPage = xaml_typename<AppWinui::AnalyticsPage>();
}
else if (tag == L"PlayPage")
{
targetPage = xaml_typename<AppWinui::PlayPage>();
}
else
{
return;
}
// Frame 跳转页面
MainFrame().Navigate(targetPage);
}Code language: C++ (cpp)
另外顶部需要引入命名空间
using namespace Microsoft::UI::Xaml;
#include "BlankPage.xaml.h"
#include "DashboardPage.xaml.h"
#include "AnalyticsPage.xaml.h"
#include "PlayPage.xaml.h"
#include <winrt/Windows.UI.Xaml.Interop.h>
using namespace winrt::Microsoft::UI::Xaml::Controls;Code language: C++ (cpp)
上面事件函数中的几个关键地方
auto selectedItem = args.SelectedItem().as<NavigationViewItem>(); 获取当前用户选择的菜单项
hstring tag = unbox_value<hstring>(selectedItem.Tag()); 获取菜单项里面的Tag,就是我们上面再xaml中配置的Tab 对应的页面名。
winrt::Windows::UI::Xaml::Interop::TypeName targetPage; 定义一个用来存放页面名称的类型名字,为后面的MainFrame().Navigate(targetPage); 做参数,进行跳转。
if (tag == L"DashboardPage")
{
targetPage = xaml_typename<AppWinui::DashboardPage>();
}Code language: C++ (cpp)
根据,不同的tag名字,然后创建不同的targetPage 。
MainFrame().Navigate(targetPage);最终跳转。
完整代码
#include "pch.h"
#include "MainWindow.xaml.h"
#if __has_include("MainWindow.g.cpp")
#include "MainWindow.g.cpp"
#endif
using namespace winrt;
using namespace Microsoft::UI::Xaml;
#include "BlankPage.xaml.h"
#include "DashboardPage.xaml.h"
#include "AnalyticsPage.xaml.h"
#include "PlayPage.xaml.h"
#include <winrt/Windows.UI.Xaml.Interop.h>
using namespace winrt::Microsoft::UI::Xaml::Controls;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace winrt::AppWinui::implementation
{
MainWindow::MainWindow()
{
InitializeComponent();
MainFrame().Navigate(xaml_typename<AppWinui::BlankPage>());
}
int32_t MainWindow::MyProperty()
{
throw hresult_not_implemented();
}
void MainWindow::MyProperty(int32_t /* value */)
{
throw hresult_not_implemented();
}
}
void winrt::AppWinui::implementation::MainWindow::OnNavViewSelectionChanged(winrt::Microsoft::UI::Xaml::Controls::NavigationView const& sender,
winrt::Microsoft::UI::Xaml::Controls::NavigationViewSelectionChangedEventArgs const& args)
{
// 获取选中的菜单项
auto selectedItem = args.SelectedItem().as<NavigationViewItem>();
if (!selectedItem) return;
// 取出 Tag 字符串
hstring tag = unbox_value<hstring>(selectedItem.Tag());
winrt::Windows::UI::Xaml::Interop::TypeName targetPage;
// 根据 Tag 匹配页面类型
if (tag == L"DashboardPage")
{
targetPage = xaml_typename<AppWinui::DashboardPage>();
}
else if (tag == L"AnalyticsPage")
{
targetPage = xaml_typename<AppWinui::AnalyticsPage>();
}
else if (tag == L"PlayPage")
{
targetPage = xaml_typename<AppWinui::PlayPage>();
}
else
{
return;
}
// Frame 跳转页面
MainFrame().Navigate(targetPage);
}
Code language: C++ (cpp)
源码下载地址