두 페이지 간의 탐색 구현
앱에서 기본 피어 투 피어 탐색을 할 수 있도록 프레임과 페이지를 사용하는 방법을 알아봅니다.
거의 모든 앱에는 페이지 간 탐색이 필요합니다. 단일 콘텐츠 페이지가 있는 간단한 앱에도 일반적으로 탐색이 필요한 설정 페이지가 있습니다. 이 문서에서는 앱에 XAML Page
을 추가하고 Frame
페이지 간 탐색을 사용하는 기본 사항을 안내합니다.
Important
이 예제에서는 Microsoft Visual Studio의 빈 앱 템플릿을 사용합니다. Windows 앱 SDK/WinUI 3 앱 및 UWP 앱용 템플릿에는 차이가 있으므로 앱 유형에 맞는 탭을 선택해야 합니다.
- 적용 대상: Windows 앱 SDK/WinUI3
- 중요 API: Microsoft.UI.Xaml.Controls.Frame 클래스, Microsoft.UI.Xaml.Controls.Page 클래스, Microsoft.UI.Xaml.Navigation 네임스페이스
1. 비어 있는 앱 만들기
Visual Studio에서 빈 앱을 만들려면
- 개발 컴퓨터를 설정하려면 Windows 앱 SDK용 도구 설치를 참조하세요.
- Microsoft Visual Studio 시작 창에서, 새 프로젝트 만들기를 선택하거나 Visual Studio 메뉴에서 파일>신규>프로젝트를 선택합니다.
- 이 새 프로젝트 만들기 대화 상자의 드롭다운 필터에서, C# 또는 C++, Windows, 및 WinUI를 각각 선택합니다.
- 비어 있는 앱, 패키지됨(데스크톱의 WinUI 3) 프로젝트 템플릿을 선택하고 다음을 클릭합니다. 이 템플릿은 WinUI 3 기반 사용자 인터페이스를 갖춘 데스크톱 앱을 만듭니다.
- 이 프로젝트 이름 상자에서,
BasicNavigation
를 입력한 후, 만들기를 클릭합니다. - 프로그램을 실행하려면 디버그>디버깅 시작 을 메뉴에서 선택하거나 F5 키를 누릅니다. 개발 컴퓨터에서 솔루션을 빌드하고 실행하여 앱이 오류 없이 실행되는지 확인합니다. 빈 페이지가 표시됩니다.
- 디버깅을 중지하고 Visual Studio로 돌아가려면 앱을 종료하거나, 메뉴에서 디버깅 중지를 클릭합니다.
- 제거할 예제 코드가 있는 템플릿은
MainWindow.xaml
및MainWindow
코드 숨김 파일에 위치합니다.
팁
자세한 내용은 첫 번째 WinUI 3(Windows 앱 SDK) 프로젝트 만들기를 참조하세요.
2. 프레임을 사용하여 페이지 간 이동
앱에 여러 페이지가 있는 경우 프레임 을 사용하여 페이지 사이를 탐색합니다. 이 Frame
클래스에서는 Navigate, GoBack, 및 GoForward같은 다양한 탐색 메서드와 BackStack, ForwardStack, 및 BackStackDepth같은 속성을 지원합니다.
Visual Studio에서 새 Windows 앱 SDK 프로젝트를 만들 때 프로젝트 템플릿은 MainWindow
클래스( Microsoft.UI.Xaml.Window 형식))를 만듭니다. 그러나 프레임 또는 페이지 를 만들지 않고 탐색 코드도 제공하지 않습니다.
페이지 간 탐색을 활성화하려면 Frame
를 MainWindow
루트 요소로 추가합니다. 작업을 수행할 수 있는 Application.OnLaunched 메서드 재정의는 App.xaml
코드 숨김 파일에 있습니다. 이 App
코드 숨김 파일을 열고 OnLaunched
재정의를 업데이트하며, 여기에 표시된 대로 NavigationFailed 이벤트를 처리합니다.
// App.xaml.cs
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
{
m_window = new MainWindow();
// Create a Frame to act as the navigation context and navigate to the first page
Frame rootFrame = new Frame();
rootFrame.NavigationFailed += OnNavigationFailed;
// Navigate to the first page, configuring the new page
// by passing required information as a navigation parameter
rootFrame.Navigate(typeof(MainPage), args.Arguments);
// Place the frame in the current Window
m_window.Content = rootFrame;
// Ensure the MainWindow is active
m_window.Activate();
}
void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
{
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
}
// App.xaml.h
// Add after OnLaunched declaration.
void OnNavigationFailed(IInspectable const&, Microsoft::UI::Xaml::Navigation::NavigationFailedEventArgs const&);
///////////////
// App.xaml.cpp
void App::OnLaunched(LaunchActivatedEventArgs const& e)
{
window = make<MainWindow>();
Frame rootFrame = Frame();
rootFrame.NavigationFailed({ this, &App::OnNavigationFailed });
rootFrame.Navigate(xaml_typename<BasicNavigation::MainPage>(), box_value(e.Arguments()));
window.Content(rootFrame);
window.Activate();
}
void App::OnNavigationFailed(IInspectable const&, NavigationFailedEventArgs const& e)
{
throw hresult_error(E_FAIL, hstring(L"Failed to load Page ") + e.SourcePageType().Name);
}
참고 항목
탐색이 더 복잡한 앱의 경우, 일반적으로 NavigationView 를 MainWindow의 루트로 사용하고, Frame
를 탐색 뷰의 콘텐츠로 배치합니다. 자세한 정보는, 탐색 뷰를 참조하세요.
이 Navigate 메서드는 Frame
의 콘텐츠를 표시하는 데 사용됩니다. 여기서, MainPage.xaml
는 Navigate
메서드에 전달되므로, 메서드는 MainPage
을 Frame
로 로드합니다.
앱의 초기 창 탐색에 실패하면, NavigationFailed
이벤트가 발생하고 이 코드는 이벤트 처리기에서 예외를 throw합니다.
3. 기본 페이지 추가
이 빈 앱 템플릿은 여러 앱 페이지를 만들지 않습니다. 페이지 간에 탐색하려면 앱에 일부 페이지를 추가해야 합니다.
앱에 새 항목을 추가하려면 다음을 수행합니다.
- 이 솔루션 탐색기에서,
BasicNavigation
프로젝트 노드를 마우스 우클릭하여 컨텍스트 메뉴를 엽니다. - 컨텍스트 메뉴에서 추가>새 항목 을 선택합니다.
- 이 새 항목 추가 대화 상자에서, 왼쪽 창에서 WinUI 노드를 선택한 후, 빈 페이지(WinUI 3) 를 가운데 창에서 선택합니다.
- 이 이름 상자에 입력하고
MainPage
누를 버튼은 추가 버튼입니다. - 1-4단계를 반복하여 두 번째 페이지를 추가하지만 이름 상자에
Page2
입력합니다.
이제, 이 파일은 BasicNavigation
프로젝트의 일부로 나열됩니다.
C# | C++ |
---|---|
|
|
Important
C++ 프로젝트의 경우, 다른 페이지를 참조하는 각 페이지의 헤더 파일에 #include
지시문을 추가해야 합니다. 여기에 표시된 페이지 간 탐색 예제의 경우, mainpage.xaml.h 파일에는 #include "Page2.xaml.h"
이 포함되는 반면, page2.xaml.h에는 #include "MainPage.xaml.h"
이 포함됩니다.
C++ 페이지 템플릿에는 Button
예제를 포함하고 XAML 및 페이지의 코드 숨김 파일에서 제거해야 하는 클릭 처리기 코드도 포함됩니다.
페이지에 콘텐츠 추가
이 MainPage.xaml
에서, 기존 페이지 콘텐츠를 다음 콘텐츠로 대체합니다.
<Grid>
<TextBlock x:Name="pageTitle" Text="Main Page"
Margin="16" Style="{StaticResource TitleTextBlockStyle}"/>
<HyperlinkButton Content="Click to go to page 2"
Click="HyperlinkButton_Click"
HorizontalAlignment="Center"/>
</Grid>
이 XAML은 다음을 추가합니다.
- 이 TextBlock 요소의 이름은
pageTitle
로 Text 속성을 갖고 있는데,Main Page
루트 Grid의 자식 요소로 설정되어 있습니다. - 이 HyperlinkButton 요소는 루트 Grid자식 요소로서 다음 페이지로 이동하는 데 사용됩니다.
이 MainPage
코드 숨김 파일에, 다음의 파일을 추가하세요. 이는 Click
이벤트가 위치한 HyperlinkButton 을 통해 Page2.xaml
로의 탐색을 활성화하기 위함입니다.
// MainPage.xaml.cs
private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
{
Frame.Navigate(typeof(Page2));
}
// pch.h
// Add this include in pch.h to support winrt::xaml_typename
#include <winrt/Windows.UI.Xaml.Interop.h>
////////////////////
// MainPage.xaml.h
void HyperlinkButton_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e);
////////////////////
// MainPage.xaml.cpp
void winrt::BasicNavigation::implementation::MainPage::HyperlinkButton_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e)
{
Frame().Navigate(winrt::xaml_typename<BasicNavigation::Page2>());
}
MainPage
은 Page 클래스의 하위 클래스입니다. 이 Page
클래스는 읽기 전용 Frame 속성을 갖고 있으며, Frame
이 Page
를 포함하고 있습니다. 만약 Click
이 HyperlinkButton
이벤트 호출기가 있는 MainPage
여기에서 해당 호출기로 Frame.Navigate(typeof(Page2))
를 호출한다면, Frame
는 Page2.xaml
해당 내용을 표시합니다.
페이지가 프레임에 로드될 때마다, 페이지는 PageStackEntry 로서 BackStack 또는 ForwardStack 에 추가되는데, 그 위치는 Frame입니다. 이를 통해 기록 및 뒤로 탐색을 사용할 수 있습니다.
이제, Page2.xaml
에서 동일한 작업을 수행합니다. 기존 페이지의 콘텐츠를 다음 콘텐츠로 대체합니다.
<Grid>
<TextBlock x:Name="pageTitle" Text="Page 2"
Margin="16" Style="{StaticResource TitleTextBlockStyle}"/>
<HyperlinkButton Content="Click to go to main page"
Click="HyperlinkButton_Click"
HorizontalAlignment="Center"/>
</Grid>
이 Page2
코드 숨김 파일에서, 다음의 파일을 추가하여 처리할 Click
이벤트의 위치는 HyperlinkButton 이며, 이는 MainPage.xaml
를 탐색하기 위한 작업입니다.
// Page2.xaml.cs
private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
{
Frame.Navigate(typeof(MainPage));
}
// Page2.xaml.h
void HyperlinkButton_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e);
/////////////////
// Page2.xaml.cpp
void winrt::BasicNavigation::implementation::Page2::HyperlinkButton_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e)
{
Frame().Navigate(winrt::xaml_typename<BasicNavigation::MainPage>());
}
앱을 빌드하고 실행합니다. "2페이지로 이동하려면 클릭하세요"라는 링크를 클릭합니다. 맨 위에 있는 "페이지 2"가 표시된 두 번째 페이지를 로드하고 프레임에 표시해야 합니다. 이제 2페이지의 링크를 클릭하여 기본 페이지로 돌아갑니다.
4. 페이지 간에 정보 전달
이제 앱이 두 페이지 사이를 탐색하지만 아직 흥미로운 작업을 수행하지는 않습니다. 앱에 여러 페이지가 있는 경우 페이지에서 정보를 공유해야 하는 경우가 많습니다. 이제 첫 번째 페이지에서 두 번째 페이지로 일부 정보를 전달합니다.
이 MainPage.xaml
에서, 이전에 추가한 HyperlinkButton
를 다음 StackPanel로 바꿉니다. 그러면 텍스트 문자열을 입력하기 위한 TextBlock 레이블과 TextBox name
가 추가됩니다.
<StackPanel VerticalAlignment="Center">
<TextBlock HorizontalAlignment="Center" Text="Enter your name"/>
<TextBox HorizontalAlignment="Center" Width="200" x:Name="name"/>
<HyperlinkButton Content="Click to go to page 2"
Click="HyperlinkButton_Click"
HorizontalAlignment="Center"/>
</StackPanel>
이제 Navigate
메서드의 두 번째 오버로드를 사용하고 두 번째 매개 변수로서 텍스트 상자의 텍스트를 전달합니다. 다음은 Navigate
오버로드의 시그니처입니다.
public bool Navigate(System.Type sourcePageType, object parameter);
bool Navigate(TypeName const& sourcePageType, IInspectable const& parameter);
이 HyperlinkButton_Click
이벤트 처리기가 있는 위치는 MainPage
코드 숨김 파일인데, 여기 있는 이벤트 처리기에서 두 번째 매개 변수를 더할 Navigate
메서드가 참조할 Text
속성의 위치는 name
텍스트 상자입니다.
// MainPage.xaml.cs
private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
{
Frame.Navigate(typeof(Page2), name.Text);
}
// MainPage.xaml.cpp
void winrt::BasicNavigation::implementation::MainPage::HyperlinkButton_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e)
{
Frame().Navigate(xaml_typename<BasicNavigation::Page2>(), winrt::box_value(name().Text()));
}
이 Page2.xaml
에서, 기존에 추가한 HyperlinkButton
를 다음 StackPanel
으로 바꿉니다. 이것으로 추가할 TextBlock 의 목적은 MainPage
에서 전달받은 텍스트 문자열을 표시하기 위함입니다.
<StackPanel VerticalAlignment="Center">
<TextBlock HorizontalAlignment="Center" x:Name="greeting"/>
<HyperlinkButton Content="Click to go to page 1"
Click="HyperlinkButton_Click"
HorizontalAlignment="Center"/>
</StackPanel>
이 Page2
코드 숨김 파일에, 다음의 코드를 추가해 OnNavigatedTo
메서드를 재정의합니다.
// Page2.xaml.cs
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (e.Parameter is string && !string.IsNullOrWhiteSpace((string)e.Parameter))
{
greeting.Text = $"Hello, {e.Parameter.ToString()}";
}
else
{
greeting.Text = "Hello!";
}
base.OnNavigatedTo(e);
}
// Page2.xaml.h
void Page2::OnNavigatedTo(Microsoft::UI::Xaml::Navigation::NavigationEventArgs const& e)
{
auto propertyValue{ e.Parameter().as<Windows::Foundation::IPropertyValue>() };
if (propertyValue.Type() == Windows::Foundation::PropertyType::String)
{
auto name{ winrt::unbox_value<winrt::hstring>(e.Parameter()) };
if (!name.empty())
{
greeting().Text(L"Hello, " + name);
__super::OnNavigatedTo(e);
return;
}
}
greeting().Text(L"Hello!");
__super::OnNavigatedTo(e);
}
앱을 실행하고 텍스트 상자에 이름을 입력한 다음 Click to go to page 2
라는 링크를 클릭합니다.
만약 Click
이벤트의 HyperlinkButton
위치가 MainPage
인 상황에서 해당 이벤트가 Frame.Navigate(typeof(Page2), name.Text)
를 호출하는 경우, name.Text
속성을 Page2
로 전달한 후, 이벤트 데이터의 값을 페이지에 표시되는 메시지를 위해 사용합니다.
5. 페이지 캐시
페이지 콘텐츠 및 상태는 기본적으로 캐시되지 않으므로, 캐시 정보를 사용하고 싶다면 앱의 각 페이지에서 이를 사용하도록 설정해야 합니다.
기본 피어 투 피어 예제에서, Click to go to page 1
링크를 Page2
에서 클릭하면, TextBox
(및 다른 필드)가 MainPage
에서 기본 상태로 설정됩니다. 이 작업을 해결하는 방법으로 NavigationCacheMode 속성을 사용하여 프레임의 페이지 캐시에 페이지를 추가하도록 지정하는 것이 있습니다.
기본적으로 탐색이 발생할 때마다 기본값을 사용하여 새 페이지 인스턴스가 만들어집니다. 이 MainPage.xaml
에서, NavigationCacheMode
를 Enabled
로 설정하여 (여는 Page
태그에서) 프레임용 페이지 캐시가 초과될 때까지 페이지를 위한 모든 콘텐츠 및 상태 값을 유지하고 페이지를 캐시합니다. NavigationCacheMode를 Required로 설정하면, 프레임에서 캐시 저장되는 탐색 기록의 페이지 수를 지정하는 CacheSize 제한을 무시할 수 있습니다. 그러나 캐시 크기 제한은 디바이스의 메모리 제한에 따라 중요할 수 있습니다.
<Page
x:Class="BasicNavigation.MainPage"
...
mc:Ignorable="d"
NavigationCacheMode="Enabled">
이제 기본 페이지로 돌아가면 입력란에 입력한 이름이 그대로 유지됩니다.
6. 페이지 전환 애니메이션 사용자 지정
기본적으로 탐색이 발생할 때 프레임의 각 페이지에 애니메이션 효과가 생깁니다. 기본 애니메이션은 페이지가 창의 아래쪽에서 위로 미끄러지도록 하는 "입장" 애니메이션입니다. 그러나 앱 탐색에 더 적합한 다양한 애니메이션 옵션을 선택할 수 있습니다. 예를 들어, "드릴 인" 애니메이션을 사용하여 사용자가 앱에 더 깊이 들어가고 있다는 느낌을 주거나 가로 슬라이드 애니메이션을 사용하여 두 페이지가 피어라는 느낌을 줄 수 있습니다. 자세한 내용은 페이지 전환을 참조하세요.
이러한 애니메이션은 NavigationTransitionInfo의 하위 클래스로 표시됩니다. 페이지 전환에 사용할 애니메이션을 지정하려면 Navigate
메서드의 세 번째 오버로드를 사용하고 NavigationTransitionInfo
하위 클래스를 세 번째 매개 변수(infoOverride
)로 전달합니다. 다음은 Navigate
오버로드의 시그니처입니다.
public bool Navigate(System.Type sourcePageType,
object parameter,
NavigationTransitionInfo infoOverride);
bool Navigate(TypeName const& sourcePageType,
IInspectable const& parameter,
NavigationTransitionInfo const& infoOverride);
이 HyperlinkButton_Click
이벤트 처리기가 MainPage
코드 숨김 파일에 위치해 잇는데, 해당 이벤트 처리기가 세 번째 매개 변수를 추가하는 Navigate
메서드에서 infoOverride
매개 변수를 SlideNavigationTransitionInfo 로 설정합니다. 또한 SlideNavigationTransitionInfo는 Effect 속성이 FromRight으로 설정되어 있습니다.
// MainPage.xaml.cs
private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
{
Frame.Navigate(typeof(Page2),
name.Text,
new SlideNavigationTransitionInfo()
{ Effect = SlideNavigationTransitionEffect.FromRight});
}
// pch.h
#include <winrt/Microsoft.UI.Xaml.Media.Animation.h>
////////////////////
// MainPage.xaml.cpp
using namespace winrt::Microsoft::UI::Xaml::Media::Animation;
// ...
void winrt::BasicNavigation::implementation::MainPage::HyperlinkButton_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e)
{
// Create the slide transition and set the transition effect to FromRight.
SlideNavigationTransitionInfo slideEffect = SlideNavigationTransitionInfo();
slideEffect.Effect(SlideNavigationTransitionEffect(SlideNavigationTransitionEffect::FromRight));
Frame().Navigate(winrt::xaml_typename<BasicNavigation::Page2>(),
winrt::box_value(name().Text()),
slideEffect);
}
이 HyperlinkButton_Click
이벤트 처리기가 Page2
코드 숨김 파일에 위치해 있는데, 해당 이벤트 처리기가 infoOverride
매개 변수를 SlideNavigationTransitionInfo 에 설정합니다. 해당 SlideNavigationTransitionInfo에는 Effect 속성이 FromLeft로 설정되어 있습니다.
// Page2.xaml.cs
private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
{
Frame.Navigate(typeof(MainPage),
null,
new SlideNavigationTransitionInfo()
{ Effect = SlideNavigationTransitionEffect.FromLeft});
}
// Page2.xaml.cpp
using namespace winrt::Microsoft::UI::Xaml::Media::Animation;
// ...
void winrt::BasicNavigation::implementation::MainPage::HyperlinkButton_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e)
{
// Create the slide transition and set the transition effect to FromLeft.
SlideNavigationTransitionInfo slideEffect = SlideNavigationTransitionInfo();
slideEffect.Effect(SlideNavigationTransitionEffect(SlideNavigationTransitionEffect::FromLeft));
Frame().Navigate(winrt::xaml_typename<BasicNavigation::MainPage>(),
nullptr,
slideEffect);
}
이제 페이지 사이를 탐색할 때 페이지가 좌우로 슬라이드로 이동하므로, 자연스럽게 전환한다는 느낌을 제공하고 페이지 간의 연결을 강화합니다.
관련된 문서
Windows developer