点击左侧导航栏打开不同的页面

上节课我们完成了,显示左侧栏,左侧栏有一个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)

主要变更:

  1. NavigationView 中增加一个事件,选择变更事件:SelectionChanged=”OnNavViewSelectionChanged”,当切换不同的菜单项触发
  2. 增加和修改了几个菜单项的,<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)

源码下载地址

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注