На прошлом занятии мы реализовали левую боковую панель с элементом 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)
Реализовать функцию переключения страниц
Поставьте курсор на имя событийной функции OnNavViewSelectionChanged в XAML, нажмите сочетание клавиш F12. Visual Studio автоматически создаст эту функцию: в заголовочном файле .h появится только объявление функции (без тела реализации), а в соответствующем .cpp создастся заготовка реализации, курсор сразу переместится в cpp-файл, править заголовок вручную не нужно.

Ниже код реализации в файле MainWindow.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)
Также в начале 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.
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)
Ссылка для скачивания исходного кода
Кликайте по пунктам левого навигационного меню для открытия разных страниц