왼쪽 탐색 바 메뉴를 클릭하면 각 페이지가 로드됩니다

지난 수업에서 왼쪽 사이드바 표시 기능을 완성했습니다. 사이드바 안에 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를 누르면 Visual Studio가 자동으로 이벤트 함수를 생성합니다. .h 헤더 파일에 함수 선언만 생성되고 구현 내용은 없으며, .cpp 파일에 구현 코드 틀이 자동으로 만들어지고 커서가 cpp로 이동합니다. 사용자가 직접 헤더 파일을 수정할 필요는 없습니다.

아래는 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()); XAML에서 설정한 Tag 속성값(이동할 페이지 이름 문자열)을 추출

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)

전체 소스 다운로드 링크

왼쪽 탐색 바 메뉴를 클릭하면 각 페이지가 로드됩니다

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다