탐색 개요
Windows Presentation Foundation (WPF)는 독립 실행형 응용 프로그램과 XAML browser applications (XBAPs)라는 두 유형의 응용 프로그램에서 사용할 수 있는 브라우저 스타일의 탐색을 지원합니다. WPF는 탐색 가능하도록 콘텐츠를 패키지하기 위해 Page 클래스를 제공합니다. Hyperlink를 사용하여 선언적으로 Page 간에 탐색하거나 NavigationService를 사용하여 프로그래밍 방식으로 탐색할 수 있습니다. WPF는 저널을 사용하여 탐색하기 전의 페이지를 기억하여 해당 페이지로 다시 탐색합니다.
Page, Hyperlink, NavigationService 및 저널은 WPF에서 제공하는 탐색 지원의 핵심 요소입니다. 이 개요에서는 느슨한 Extensible Application Markup Language (XAML) 파일, HTML 파일 및 개체로의 탐색을 포함한 고급 탐색 지원을 다루기 전에 이 기능을 자세히 살펴봅니다.
참고 |
---|
이 항목에서 "브라우저"라는 용어는 WPF 응용 프로그램을 호스팅할 수 있는 브라우저만 지칭하며 현재 Microsoft Internet Explorer 및 Firefox가 해당됩니다.특정 WPF 기능이 특정 브라우저에서만 지원되는 경우에는 브라우저 버전을 명시합니다. |
이 항목에는 다음 단원이 포함되어 있습니다.
- WPF 응용 프로그램에서 탐색
- NavigationWindow 클래스
- Frame 클래스
- 탐색 호스트
- XAML 페이지 이외의 콘텐츠 탐색
- 보안
- 관련 항목
WPF 응용 프로그램에서 탐색
이 항목에서는 WPF의 주요 탐색 기능에 대한 개요를 제공합니다. 이러한 기능은 독립 실행형 응용 프로그램과 XBAPs 모두에 사용할 수 있지만 이 항목에서는 XBAP와 관련해서만 설명합니다.
참고 |
---|
이 항목에서는 XBAPs의 빌드 및 배포 방법은 다루지 않습니다.XBAPs에 대한 자세한 내용은 WPF XAML 브라우저 응용 프로그램 개요를 참조하십시오. |
이 단원에서는 탐색과 관련된 다음 사항에 대해 설명하고 그에 대한 예제를 제공합니다.
페이지 구현
시작 페이지 구성
호스트 창의 제목, 너비 및 높이 구성
하이퍼링크 탐색
조각 탐색
탐색 서비스
탐색 서비스를 사용한 프로그래밍 방식 탐색
탐색 수명
저널을 사용하여 탐색 기억
페이지 수명 및 저널
탐색 기록으로 콘텐츠 상태 유지
쿠키
구조적 탐색
페이지 구현
WPF에서는 .NET Framework 개체, 사용자 지정 개체, 열거형 값, 사용자 컨트롤, XAML 파일 및 HTML 파일을 포함한 몇 가지 콘텐츠 형식을 탐색할 수 있습니다. 그러나 콘텐츠를 패키지하는 가장 일반적이고 편리한 방법은 Page를 사용하는 것입니다. 또한 Page는 탐색 관련 기능을 구현하여 모양을 개선하고 개발을 단순화합니다.
Page를 사용하면 다음과 같은 태그를 사용하여 탐색 가능한 XAML 콘텐츠 페이지를 선언적으로 구현할 수 있습니다.
<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" />
XAML 태그에서 구현되는 Page에는 루트 요소로 Page가 사용되며 WPF XML 네임스페이스 선언이 필요합니다. Page 요소에는 탐색하고 표시하려고 하는 콘텐츠가 포함됩니다. 다음 태그에서처럼 Page.Content 속성 요소를 설정하여 콘텐츠를 추가합니다.
<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation">
<Page.Content>
<!-- Page Content -->
Hello, Page!
</Page.Content>
</Page>
Page.Content에는 자식 요소가 하나만 포함될 수 있습니다. 앞의 예제에서 콘텐츠는 "Hello, Page!"라는 단일 문자열입니다. 실제로는 일반적으로 레이아웃 컨트롤을 자식 요소로 사용하여(레이아웃 시스템 참조) 콘텐츠를 추가하고 작성합니다.
Page 요소의 자식 요소는 Page의 콘텐츠로 고려되므로 결과적으로 명시적 Page.Content 선언을 사용할 필요가 없습니다. 다음 태그는 이전 샘플을 선언적으로 구현한 것입니다.
<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation">
<!-- Page Content -->
Hello, Page!
</Page>
이 경우에는 Page.Content가 자동으로 Page 요소의 자식 요소로 설정됩니다. 자세한 내용은 WPF 콘텐츠 모델을 참조하십시오.
태그 전용 Page는 콘텐츠 표시에 유용합니다. 하지만 Page는 사용자가 페이지와 상호 작용하는 데 사용할 수 있는 컨트롤도 표시할 수 있으며 이벤트를 처리하고 응용 프로그램 논리를 호출하여 사용자 상호 작용에 응답할 수 있습니다. 대화형 Page는 다음 예제에서처럼 태그와 코드 숨김을 함께 사용하여 구현합니다.
<Page
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.HomePage">
Hello, from the XBAP HomePage!
</Page>
Imports System.Windows.Controls ' Page
Namespace SDKSample
Partial Public Class HomePage
Inherits Page
Public Sub New()
InitializeComponent()
End Sub
End Class
End Namespace
using System.Windows.Controls; // Page
namespace SDKSample
{
public partial class HomePage : Page
{
public HomePage()
{
InitializeComponent();
}
}
}
태그 파일과 코드 숨김 파일이 함께 작동하도록 하려면 다음 구성이 필요합니다.
태그에서 Page 요소에 x:Class 특성이 포함되어야 합니다. 응용 프로그램을 빌드할 때 태그 파일에 x:Class가 있으면 Microsoft build engine (MSBuild)에서는 Page에서 파생되며 x:Class 특성에 의해 이름이 지정되는 partial 클래스를 만듭니다. 이를 위해서는 XAML 스키마에 대한 XML 네임스페이스 선언을 추가해야 합니다(xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"). 생성된 partial 클래스는 이벤트 등록을 위해 호출되고 태그에서 구현되는 속성을 설정하는 InitializeComponent를 구현합니다.
코드 숨김에서 클래스는 태그의 x:Class 특성으로 지정되는 이름과 이름이 같은 partial 클래스여야 하며 Page에서 파생되어야 합니다. 이를 통해 응용 프로그램 빌드 시 태그 파일에 대해 생성되는 partial 클래스와 코드 숨김 파일을 연결할 수 있습니다(WPF 응용 프로그램 만들기(WPF) 참조).
코드 숨김에서 Page 클래스는 InitializeComponent 메서드를 호출하는 생성자를 구현해야 합니다. InitializeComponent는 태그 파일에서 생성된 partial 클래스에 의해 구현되어 이벤트를 등록하고 태그에 정의된 속성을 설정합니다.
참고 |
---|
Microsoft Visual Studio를 사용하여 프로젝트에 새 Page를 추가하면 Page는 태그와 코드 숨김을 모두 사용하여 구현되며, 태그와 코드 숨김 파일 사이를 연결하기 위해서는 여기서 설명하는 것과 같은 구성 작업이 필요합니다. |
Page가 구현되면 이를 탐색할 수 있습니다. 응용 프로그램이 탐색할 첫 번째 Page를 지정하려면 시작 Page를 구성해야 합니다.
시작 페이지 구성
XBAPs를 사용하려면 브라우저에서 어느 정도의 응용 프로그램 인프라를 호스팅해야 합니다. WPF에서 Application 클래스는 필요한 응용 프로그램 인프라를 설정하는 응용 프로그램 정의의 일부입니다(응용 프로그램 관리 개요 참조).
응용 프로그램 정의는 일반적으로 태그와 코드 숨김 모두를 사용하여 구현되며 태그 파일은 MSBuild ApplicationDefinition 항목으로 구성됩니다. 다음은 XBAP에 대한 응용 프로그램 정의입니다.
<Application
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.App" />
Imports System.Windows ' Application
Namespace SDKSample
Partial Public Class App
Inherits Application
End Class
End Namespace
using System.Windows; // Application
namespace SDKSample
{
public partial class App : Application { }
}
XBAP는 응용 프로그램 정의를 사용하여 시작 Page를 지정하며 이 페이지는 XBAP가 시작될 때 자동으로 로드되는 Page입니다. 이렇게 하려면 원하는 Page에 대한 uniform resource identifier (URI)로 StartupUri 속성을 설정합니다.
참고 |
---|
대개의 경우 Page는 응용 프로그램으로 컴파일되거나 응용 프로그램과 함께 배포됩니다.이 경우 Page를 식별하는 URI는 pack URI이며 이는 pack 체계를 따르는 URI입니다.pack URIs에 대해서는 WPF의 Pack URI에서 자세히 다룹니다. 아래에서 설명하는 http 체계를 사용하여 콘텐츠를 탐색할 수도 있습니다. |
다음 예제에서처럼 StartupUri를 태그에서 선언적으로 설정할 수 있습니다.
<Application
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.App"
StartupUri="PageWithHyperlink.xaml" />
이 예제에서 StartupUri 특성은 HomePage.xaml을 식별하는 관련 pack URI로 설정됩니다. XBAP가 시작되면 HomePage.xaml이 자동으로 탐색되어 표시됩니다. 웹 서버에서 시작된 XBAP를 보여 주는 다음 그림에서 이를 확인할 수 있습니다.
참고 |
---|
XBAPs의 개발과 배포에 대한 자세한 내용은 WPF XAML 브라우저 응용 프로그램 개요 및 WPF 응용 프로그램 배포(WPF)를 참조하십시오. |
호스트 창의 제목, 너비 및 높이 구성
이전 그림에서 브라우저 및 탭 패널의 제목이 모두 XBAP의 URI임을 알 수 있습니다. 이 제목은 길이가 길며 모양이나 정보 제공 측면 모두에서 그다지 유용하지 않습니다. 이런 이유 때문에 Page는 WindowTitle 속성을 설정하여 제목을 변경할 수 있는 방법을 제공합니다. 또한 WindowWidth 및 WindowHeight를 설정하여 각각 브라우저 창의 너비와 높이를 구성할 수 있습니다.
다음 예제에서처럼 WindowTitle, WindowWidth 및 WindowHeight를 태그에서 선언적으로 설정할 수 있습니다.
<Page
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.HomePage"
WindowTitle="Page Title"
WindowWidth="500"
WindowHeight="200">
Hello, from the XBAP HomePage!
</Page>
다음 그림에서는 앞의 예제를 실행한 결과를 보여 줍니다.
하이퍼링크 탐색
일반적으로 XBAP는 몇 개의 페이지로 구성됩니다. 한 페이지에서 다른 페이지로 탐색하는 가장 간단한 방법은 Hyperlink를 사용하는 것입니다. 다음 태그에서 볼 수 있듯이 Hyperlink 요소를 사용하여 Page에 Hyperlink를 선언적으로 추가할 수 있습니다.
<Page
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
WindowTitle="Page With Hyperlink"
WindowWidth="250"
WindowHeight="250">
...
<Hyperlink NavigateUri="UriOfPageToNavigateTo.xaml">
Navigate to Another Page
</Hyperlink>
...
</Page>
Hyperlink 요소에는 다음이 필요합니다.
탐색할 Page의 pack URI(NavigateUri 특성으로 지정)
텍스트와 이미지처럼 사용자가 탐색을 시작하기 위해 클릭할 수 있는 콘텐츠(Hyperlink 요소에 포함될 수 있는 콘텐츠에 대해서는 Hyperlink 참조)
다음 그림에서는 Hyperlink가 있는 Page를 사용한 XBAP를 보여 줍니다.
여기서 예상할 수 있듯이 Hyperlink를 클릭하면 XBAP는 NavigateUri 특성으로 식별되는 Page를 탐색합니다. 또한 XBAP는 이전 Page의 항목을 Internet Explorer의 최신 페이지 목록에 추가합니다. 다음 그림에서 이를 확인할 수 있습니다.
Hyperlink는 Page에서 다른 페이지로의 탐색을 지원할 뿐만 아니라 조각 탐색도 지원합니다.
조각 탐색
조각 탐색은 현재 Page 또는 다른 Page의 콘텐츠 조각으로의 탐색입니다. WPF에서 콘텐츠 조각은 명명된 요소에 포함된 콘텐츠입니다. 명명된 요소는 Name 특성이 설정된 요소입니다. 다음 태그에서 콘텐츠 조각이 포함된 명명된 TextBlock 요소를 볼 수 있습니다.
<Page
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
WindowTitle="Page With Fragments" >
...
<!-- Content Fragment called "Fragment1" -->
<TextBlock Name="Fragment1">
Ea vel dignissim te aliquam facilisis ...
</TextBlock>
...
</Page>
Hyperlink가 콘텐츠 조각을 탐색하려면 NavigateUri 특성에 다음이 포함되어야 합니다.
조각 URI의 형식은 다음과 같습니다.
PageURI#elementName
다음은 콘텐츠 조각을 탐색하도록 구성된 Hyperlink의 예제입니다.
<Page
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
WindowTitle="Page That Navigates To Fragment" >
...
<Hyperlink NavigateUri="PageWithFragments.xaml#Fragment1">
Navigate To pack Fragment
</Hyperlink>
...
</Page>
참고 |
---|
이 단원에서는 WPF의 기본 조각 탐색 구현에 대해 설명합니다.WPF에서는 부분적으로 NavigationService.FragmentNavigation 이벤트 처리가 필요한 자체 조각 탐색 체계를 구현할 수도 있습니다. |
중요 |
---|
HTTP를 통해 페이지를 탐색할 수 있는 경우에만 느슨한 XAML 페이지(Page가 루트 요소인 태그 전용 XAML 파일)에서 조각을 탐색할 수 있습니다. 그러나 느슨한 XAML 페이지는 고유한 조각을 탐색할 수 있습니다. |
탐색 서비스
Hyperlink를 사용하여 사용자는 특정 Page로의 탐색을 시작할 수 있지만 페이지를 찾고 다운로드하는 작업은 NavigationService 클래스가 수행합니다. 기본적으로 NavigationService가 Hyperlink와 같은 클라이언트 코드 대신 탐색 요청을 처리하는 기능을 제공합니다. 또한 NavigationService는 탐색 요청을 추적하고 이에 영향을 주기 위한 더 높은 수준의 지원을 구현합니다.
Hyperlink를 클릭하면 WPF는 NavigationService.Navigate를 호출하여 지정한 pack URI에서 Page를 찾고 다운로드합니다. 다운로드된 Page는 루트 개체가 다운로드된 Page의 인스턴스인 개체 트리로 변환됩니다. 루트 Page 개체에 대한 참조는 NavigationService.Content 속성에 저장됩니다. 탐색된 콘텐츠의 Pack URI는 NavigationService.Source 속성에 저장되고 NavigationService.CurrentSource에는 최근에 탐색한 페이지의 Pack URI가 저장됩니다.
참고 |
---|
WPF 응용 프로그램에는 현재 활성화된 NavigationService가 여러 개 있을 수 있습니다.자세한 내용은 이 항목 뒷부분의 탐색 호스트를 참조하십시오. |
탐색 서비스를 사용한 프로그래밍 방식 탐색
Hyperlink에서 사용자 대신 NavigationService를 사용하기 때문에 Hyperlink를 사용하여 탐색을 태그에서 선언적으로 구현하는 경우에는 NavigationService에 대해 알 필요가 없습니다. 즉, Hyperlink의 직접 또는 간접 부모가 탐색 호스트이면(탐색 호스트 참조) Hyperlink는 탐색 호스트의 탐색 서비스를 찾고 이를 사용하여 탐색 요청을 처리할 수 있습니다.
하지만 다음과 같이 NavigationService를 직접 사용해야 하는 경우가 있습니다.
이러한 상황에서는 NavigationService 개체의 Navigate 메서드를 호출하여 탐색을 프로그래밍 방식으로 시작하는 코드를 작성해야 합니다. 이렇게 하려면 NavigationService에 대한 참조를 가져와야 합니다.
NavigationService에 대한 참조 가져오기
탐색 호스트 단원에서 다룬 이유 때문에 WPF 응용 프로그램에는 둘 이상의 NavigationService가 있을 수 있습니다. 즉, 일반적으로 현재 Page를 탐색한 NavigationService인 NavigationService를 찾을 방법을 코드에 지정해야 합니다. static NavigationService.GetNavigationService 메서드를 호출하여 NavigationService에 대한 참조를 가져올 수 있습니다. 특정 Page를 탐색한 NavigationService를 가져오려면 Page에 대한 참조를 GetNavigationService 메서드의 인수로 전달합니다. 다음 코드에서는 현재 Page에 대한 NavigationService를 가져오는 방법을 보여 줍니다.
' Get a reference to the NavigationService that navigated to this Page
Dim ns As NavigationService = NavigationService.GetNavigationService(Me)
using System.Windows.Navigation; // NavigationServce
...
// Get a reference to the NavigationService that navigated to this Page
NavigationService ns = NavigationService.GetNavigationService(this);
Page에 대한 NavigationService를 쉽게 찾기 위해 Page는 NavigationService 속성을 구현합니다. 다음 예제에서 이를 확인할 수 있습니다.
' Get a reference to the NavigationService that navigated to this Page
Dim ns As NavigationService = Me.NavigationService
using System.Windows.Navigation; // NavigationServce
...
// Get a reference to the NavigationService that navigated to this Page
NavigationService ns = this.NavigationService;
참고 |
---|
Page는 Page에서 Loaded 이벤트가 발생한 경우에만 NavigationService에 대한 참조를 가져올 수 있습니다. |
프로그래밍 방식으로 페이지 개체 탐색
다음 예제에서는 NavigationService를 사용하여 프로그래밍 방식으로 Page를 탐색하는 방법을 보여 줍니다. 탐색할 Page는 하나의 기본값이 아닌 생성자를 사용해야 인스턴스화할 수 있기 때문에 프로그래밍 방식 탐색이 필요합니다. 기본값이 아닌 생성자를 사용하는 Page는 다음 태그와 코드에서 볼 수 있습니다.
<Page
x:Class="SDKSample.PageWithNonDefaultConstructor"
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
Title="PageWithNonDefaultConstructor">
<!-- Content goes here -->
</Page>
Namespace SDKSample
Partial Public Class PageWithNonDefaultConstructor
Inherits Page
Public Sub New(ByVal message As String)
InitializeComponent()
Me.Content = message
End Sub
End Class
End Namespace
using System.Windows.Controls; // Page
namespace SDKSample
{
public partial class PageWithNonDefaultConstructor : Page
{
public PageWithNonDefaultConstructor(string message)
{
InitializeComponent();
this.Content = message;
}
}
}
기본값이 아닌 생성자로 Page를 탐색하는 Page는 다음 태그와 코드에서 볼 수 있습니다.
<Page
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.NSNavigationPage">
<Hyperlink Click="hyperlink_Click">
Navigate to Page with Non-Default Constructor
</Hyperlink>
</Page>
Namespace SDKSample
Partial Public Class NSNavigationPage
Inherits Page
Public Sub New()
InitializeComponent()
End Sub
Private Sub hyperlink_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
' Instantiate the page to navigate to
Dim page As New PageWithNonDefaultConstructor("Hello!")
' Navigate to the page, using the NavigationService
Me.NavigationService.Navigate(page)
End Sub
End Class
End Namespace
using System.Windows; // RoutedEventArgs
using System.Windows.Controls; // Page
using System.Windows.Navigation; // NavigationService
namespace SDKSample
{
public partial class NSNavigationPage : Page
{
public NSNavigationPage()
{
InitializeComponent();
}
void hyperlink_Click(object sender, RoutedEventArgs e)
{
// Instantiate the page to navigate to
PageWithNonDefaultConstructor page = new PageWithNonDefaultConstructor("Hello!");
// Navigate to the page, using the NavigationService
this.NavigationService.Navigate(page);
}
}
}
이 Page에서 Hyperlink를 클릭하면 Page를 인스턴스화하여 기본값이 아닌 생성자를 통해 탐색하고 NavigationService.Navigate 메서드를 호출하여 탐색을 시작합니다. Navigate는 Pack URI가 아니라 NavigationService가 탐색할 개체에 대한 참조를 받습니다.
pack URI를 사용하여 프로그래밍 방식으로 탐색
pack URI를 프로그래밍 방식으로 생성하려면(예를 들어 런타임에만 pack URI를 확인할 수 있는 경우) NavigationService.Navigate 메서드를 사용할 수 있습니다. 다음 예제에서 이를 확인할 수 있습니다.
<Page
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.NSUriNavigationPage">
<Hyperlink Click="hyperlink_Click">Navigate to Page by Pack URI</Hyperlink>
</Page>
Namespace SDKSample
Partial Public Class NSUriNavigationPage
Inherits Page
Public Sub New()
InitializeComponent()
End Sub
Private Sub hyperlink_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
' Create a pack URI
Dim uri As New Uri("AnotherPage.xaml", UriKind.Relative)
' Get the navigation service that was used to
' navigate to this page, and navigate to
' AnotherPage.xaml
Me.NavigationService.Navigate(uri)
End Sub
End Class
End Namespace
using System; // Uri, UriKind
using System.Windows; // RoutedEventArgs
using System.Windows.Controls; // Page
using System.Windows.Navigation; // NavigationService
namespace SDKSample
{
public partial class NSUriNavigationPage : Page
{
public NSUriNavigationPage()
{
InitializeComponent();
}
void hyperlink_Click(object sender, RoutedEventArgs e)
{
// Create a pack URI
Uri uri = new Uri("AnotherPage.xaml", UriKind.Relative);
// Get the navigation service that was used to
// navigate to this page, and navigate to
// AnotherPage.xaml
this.NavigationService.Navigate(uri);
}
}
}
현재 페이지 새로 고침
pack URI가 NavigationService.Source 속성에 저장된 pack URI와 같은 Page는 다운로드되지 않습니다. WPF가 현재 페이지를 다시 다운로드하도록 하려면 다음 예제에서처럼 NavigationService.Refresh 메서드를 호출하면 됩니다.
<Page
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.NSRefreshNavigationPage">
<Hyperlink Click="hyperlink_Click">Refresh this page</Hyperlink>
</Page>
Namespace SDKSample
Partial Public Class NSRefreshNavigationPage
Inherits Page
...
Private Sub hyperlink_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
' Force WPF to download this page again
Me.NavigationService.Refresh()
End Sub
End Class
End Namespace
using System.Windows; // RoutedEventArgs
using System.Windows.Controls; // Page
using System.Windows.Navigation; // NavigationService
namespace SDKSample
{
public partial class NSRefreshNavigationPage : Page
{
...
void hyperlink_Click(object sender, RoutedEventArgs e)
{
// Force WPF to download this page again
this.NavigationService.Refresh();
}
}
}
탐색 수명
지금까지 살펴본 것처럼 탐색을 시작하는 방법에는 여러 가지가 있습니다. 탐색이 시작될 때와 탐색이 진행 중일 때는 NavigationService로 구현되는 다음 이벤트를 사용하여 탐색을 추적하고 탐색에 영향을 줄 수 있습니다.
Navigating. 새 탐색이 요청될 때 발생합니다. 탐색을 취소할 때 사용할 수 있습니다.
NavigationProgress. 다운로드 도중 탐색 진행률 정보를 제공하기 위해 주기적으로 발생합니다.
Navigated. 페이지를 찾아서 다운로드할 때 발생합니다.
NavigationStopped. StopLoading을 호출하여 탐색이 중지되었거나 현재 탐색이 진행 중인데 새 탐색이 요청될 때 발생합니다.
NavigationFailed. 요청된 콘텐츠로 이동하면서 오류가 발생한 경우에 발생합니다.
LoadCompleted. 탐색된 콘텐츠가 로드 및 구문 분석되어 렌더링되기 시작할 때 발생합니다.
FragmentNavigation. 콘텐츠 조각을 탐색할 때 발생합니다. 발생하는 시점은 다음과 같습니다.
원하는 조각이 현재 콘텐츠에 있는 경우에는 즉시
원하는 조각이 다른 콘텐츠에 있는 경우에는 소스 콘텐츠가 로드된 후
탐색 이벤트는 다음 그림에 표시된 순서대로 발생합니다.
일반적으로 Page는 이러한 이벤트와는 관련이 없습니다. 응용 프로그램과 관련될 가능성이 더 크며, 이런 이유 때문에 이러한 이벤트는 Application 클래스에 의해 발생하기도 합니다.
NavigationService가 이벤트를 발생시킬 때마다 Application 클래스가 해당 이벤트를 발생시킵니다. Frame 및 NavigationWindow는 각 범위 내에서 탐색을 감지하기 위한 동일한 이벤트를 제공합니다.
경우에 따라 Page에 이러한 이벤트가 필요할 수 있습니다. 예를 들어 Page는 탐색을 취소할지 여부를 결정하기 위해 NavigationService.Navigating 이벤트를 처리할 수 있습니다. 다음 예제에서 이를 확인할 수 있습니다.
<Page
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.CancelNavigationPage">
<Button Click="button_Click">Navigate to Another Page</Button>
</Page>
Namespace SDKSample
Partial Public Class CancelNavigationPage
Inherits Page
Public Sub New()
InitializeComponent()
' Can only access the NavigationService when the page has been loaded
AddHandler Loaded, AddressOf CancelNavigationPage_Loaded
AddHandler Unloaded, AddressOf CancelNavigationPage_Unloaded
End Sub
Private Sub button_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
' Force WPF to download this page again
Me.NavigationService.Navigate(New Uri("AnotherPage.xaml", UriKind.Relative))
End Sub
Private Sub CancelNavigationPage_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
AddHandler NavigationService.Navigating, AddressOf NavigationService_Navigating
End Sub
Private Sub CancelNavigationPage_Unloaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
RemoveHandler NavigationService.Navigating, AddressOf NavigationService_Navigating
End Sub
Private Sub NavigationService_Navigating(ByVal sender As Object, ByVal e As NavigatingCancelEventArgs)
' Does the user really want to navigate to another page?
Dim result As MessageBoxResult
result = MessageBox.Show("Do you want to leave this page?", "Navigation Request", MessageBoxButton.YesNo)
' If the user doesn't want to navigate away, cancel the navigation
If result = MessageBoxResult.No Then
e.Cancel = True
End If
End Sub
End Class
End Namespace
using System; // Uri, UriKind
using System.Windows; // RoutedEventArgs, MessageBox, MessageBoxResult
using System.Windows.Controls; // Page
using System.Windows.Navigation; // NavigationService, NavigatingCancelEventArgs
namespace SDKSample
{
public partial class CancelNavigationPage : Page
{
public CancelNavigationPage()
{
InitializeComponent();
// Can only access the NavigationService when the page has been loaded
this.Loaded += new RoutedEventHandler(CancelNavigationPage_Loaded);
this.Unloaded += new RoutedEventHandler(CancelNavigationPage_Unloaded);
}
void button_Click(object sender, RoutedEventArgs e)
{
// Force WPF to download this page again
this.NavigationService.Navigate(new Uri("AnotherPage.xaml", UriKind.Relative));
}
void CancelNavigationPage_Loaded(object sender, RoutedEventArgs e)
{
this.NavigationService.Navigating += new NavigatingCancelEventHandler(NavigationService_Navigating);
}
void CancelNavigationPage_Unloaded(object sender, RoutedEventArgs e)
{
this.NavigationService.Navigating -= new NavigatingCancelEventHandler(NavigationService_Navigating);
}
void NavigationService_Navigating(object sender, NavigatingCancelEventArgs e)
{
// Does the user really want to navigate to another page?
MessageBoxResult result;
result = MessageBox.Show("Do you want to leave this page?", "Navigation Request", MessageBoxButton.YesNo);
// If the user doesn't want to navigate away, cancel the navigation
if (result == MessageBoxResult.No) e.Cancel = true;
}
}
}
앞의 예제에서처럼 처리기를 Page의 탐색 이벤트에 대해 등록한 경우 이벤트 처리기를 등록 해제해야 합니다. 등록 해제하지 않으면 WPF 탐색이 저널을 사용하여 Page 탐색을 기억하는 방식과 관련하여 예기치 않은 결과가 발생할 수 있습니다.
저널을 사용하여 탐색 기억
WPF는 백 스택 및 정방향 스택의 두 스택을 사용하여 사용자가 탐색한 페이지를 기억합니다. 현재 Page에서 새 Page로 탐색하거나 기존 Page로 이동하면 현재 Page가 백 스택에 추가됩니다. 현재 Page에서 다시 이전 Page로 탐색하면 현재 Page가 정방향 스택에 추가됩니다. 백 스택, 정방향 스택 및 이를 관리하는 기능을 통칭하여 저널이라고 합니다. 백 스택과 정방향 스택의 각 항목은 JournalEntry 클래스의 인스턴스이며 저널 항목이라고 합니다.
Internet Explorer에서 저널 탐색
개념적으로 보면 저널은 Internet Explorer의 뒤로 및 앞으로 단추와 같은 방식으로 작동합니다. 다음 그림에서 이를 확인할 수 있습니다.
Internet Explorer에서 호스팅되는 XBAPs의 경우 WPF는 저널을 Internet Explorer의 탐색 UI에 통합합니다. 이를 통해 사용자는 Internet Explorer의 뒤로, 앞으로 및 최신 페이지 단추를 사용하여 XBAP에서 페이지를 탐색할 수 있습니다. Microsoft Internet Explorer 6에는 저널이 Internet Explorer 7 또는 Internet Explorer 8에서와 같은 방식으로 통합되지 않습니다. 대신 WPF가 대체 탐색 UI를 렌더링합니다.
중요 |
---|
Internet Explorer에서는 사용자가 XBAP 내외부로 탐색하면 활성 상태가 아닌 페이지에 대한 저널 항목만 저널에 유지됩니다.페이지 활성화 유지에 대한 자세한 내용은 이 항목 뒷부분의 페이지 수명 및 저널을 참조하십시오. |
기본적으로 Internet Explorer의 최신 페이지 목록에 나타나는 각 Page에 대한 텍스트는 Page의 URI입니다. 하지만 이러한 텍스트가 사용자에게는 그다지 유용하지 않습니다. 다행히 다음 옵션 중 하나를 사용하여 이 텍스트를 변경할 수 있습니다.
연결된 JournalEntry.Name 특성 값
Page.Title 특성 값
Page.WindowTitle 특성 값과 현재 Page에 대한 URI
현재 Page에 대한 URI. (기본값)
옵션이 나열된 순서는 텍스트 검색 우선 순위의 순서와 같습니다. 예를 들어 JournalEntry.Name을 설정하면 다른 값은 무시됩니다.
다음 예제에서는 Page.Title 특성을 사용하여 저널 항목에 대해 나타나는 텍스트를 변경합니다.
<Page
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.PageWithTitle"
Title="This is the title of the journal entry for this page.">
...
</Page>
Namespace SDKSample
Partial Public Class PageWithTitle
Inherits Page
...
End Class
End Namespace
using System.Windows.Controls; // Page
namespace SDKSample
{
public partial class PageWithTitle : Page
{
...
}
}
WPF를 사용하여 저널 탐색
사용자는 Internet Explorer에서 뒤로, 앞으로 및 최신 페이지를 사용하여 저널을 탐색할 수 있지만 개발자는 WPF에서 제공하는 프로그래밍 방식과 선언적 방식을 모두 사용하여 저널을 탐색할 수 있습니다. 저널을 프로그래밍 방식과 선언적 방식으로 탐색하는 이유는 페이지에 사용자 지정 탐색 UIs를 제공하기 위해서입니다.
NavigationCommands로 노출되는 탐색 명령을 사용하여 저널 탐색 지원을 선언적으로 추가할 수 있습니다. 다음 예제에서는 BrowseBack 탐색 명령을 사용하는 방법을 보여 줍니다.
<Page
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.NavigationCommandsPage">
...
<Hyperlink Command="NavigationCommands.BrowseBack">Back</Hyperlink>
...
<Hyperlink Command="NavigationCommands.BrowseForward">Forward</Hyperlink>
...
</Page>
NavigationService 클래스의 다음 멤버 중 하나를 사용하여 저널을 프로그래밍 방식으로 탐색할 수 있습니다.
또한 이 항목 뒷부분의 탐색 기록으로 콘텐츠 상태 유지의 설명대로 저널을 프로그래밍 방식으로 조작할 수도 있습니다.
페이지 수명 및 저널
그래픽, 애니메이션 및 미디어가 포함된 풍부한 콘텐츠가 들어 있는 페이지 몇 개가 있는 XBAP를 고려해 보겠습니다. 이러한 페이지가 차지하는 메모리 공간 크기는 꽤 클 수 있으며 특히 비디오나 오디오 미디어가 사용되는 경우에는 더욱 그렇습니다. 저널은 사용자가 탐색한 페이지를 "기억"한다는 점을 고려하면 이러한 XBAP는 꽤 많은 메모리를 빠르게 소비할 수 있습니다.
이런 이유 때문에 저널은 기본적으로 Page 개체에 대한 참조가 아니라 각 저널 항목에 Page 메타데이터를 저장합니다. 저널 항목을 탐색하면 해당 Page 메타데이터를 사용하여 지정된 Page의 새 인스턴스를 만듭니다. 그 결과 탐색되는 각 Page에는 다음 그림에서 설명하는 수명이 있습니다.
기본 저널링 동작을 사용하면 메모리 소비를 줄일 수 있지만 페이지당 렌더링 성능이 저하될 수 있습니다. 특히 콘텐츠가 많은 경우에는 Page의 재초기화에 시간이 많이 걸릴 수 있습니다. Page 인스턴스를 저널에 유지해야 하는 경우에는 두 가지 방법을 사용할 수 있습니다. 첫 번째로, NavigationService.Navigate 메서드를 호출하여 프로그래밍 방식으로 Page 개체를 탐색할 수 있습니다.
두 번째로, KeepAlive 속성을 true로 설정하여(기본값은 false) WPF가 저널에 Page의 인스턴스를 유지하도록 지정할 수 있습니다. 다음 예제에서처럼 KeepAlive를 태그에서 선언적으로 설정할 수 있습니다.
<Page
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.KeepAlivePage"
KeepAlive="True">
An instance of this page is stored in the journal.
</Page>
활성화가 유지되는 Page의 수명은 그렇지 않은 경우와 약간 다릅니다. 활성화가 유지되는 Page를 처음 탐색하면 활성화가 유지되지 않는 Page와 동일하게 인스턴스화됩니다. 하지만 Page의 인스턴스가 저널에 유지되기 때문에 저널에 있는 동안에는 다시 인스턴스화되지 않습니다. 결과적으로 Page를 탐색할 때마다 호출되어야 하는 초기화 논리가 Page에 있는 경우에는 이를 생성자에서 Loaded 이벤트에 대한 처리기로 이동해야 합니다. 다음 그림에서 볼 수 있듯이 Loaded 및 Unloaded 이벤트는 Page를 탐색하거나 여기에서 다른 페이지로 탐색할 때마다 계속 발생합니다.
Page가 활성 상태로 유지되지 않는 경우에는 다음을 수행하지 않아도 됩니다.
이 페이지 또는 이 페이지의 일부에 대한 참조 저장
이벤트 처리기를 이 페이지에서 구현되지 않는 이벤트에 등록
이 두 가지 중 하나를 수행하면 Page가 저널에서 제거된 뒤에도 메모리에 유지되도록 하는 참조가 만들어집니다.
일반적으로 Page의 활성 상태를 유지하지 않는 Page의 기본 동작을 선호합니다. 하지만 이러한 기본 동작은 다음 단원에서 설명하는 상태 문제가 있습니다.
탐색 기록으로 콘텐츠 상태 유지
Page가 활성 상태로 유지되지 않으며 사용자로부터 데이터를 수집하는 컨트롤이 있는 경우 사용자가 Page에서 다른 곳으로 탐색했다 다시 돌아오면 데이터는 어떻게 될까요? 사용자 경험으로 보면 사용자는 이전에 입력한 데이터를 볼 수 있어야 합니다. 하지만 탐색할 때마다 Page의 새 인스턴스가 만들어지므로 데이터를 수집한 컨트롤이 다시 인스턴스화되어 데이터가 손실됩니다.
다행히 저널은 컨트롤 데이터를 포함한 데이터를 Page 탐색 간에 기억할 수 있는 기능을 지원합니다. 특히 각 Page에 대한 저널 항목은 연결된 Page 상태의 임시 컨테이너 역할을 합니다. 다음 단계는 Page에서 다른 곳으로 탐색할 때 이 지원이 사용되는 방식을 개괄적으로 보여 줍니다.
Page 페이지를 다시 탐색하면 저널을 사용하여 다음 단계가 수행됩니다.
WPF는 Page에서 다음 컨트롤이 사용될 때 자동으로 이 지원을 사용합니다.
Page가 이러한 컨트롤을 사용하면 여기에 입력된 데이터는 Page 탐색 간에 기억됩니다. 다음 그림의 Favorite Color ListBox를 통해 이를 확인할 수 있습니다.
Page에 이전 목록의 컨트롤 이외의 컨트롤이 있거나 상태가 사용자 지정 개체에 저장된 경우에는 저널이 상태를 Page 탐색 간에 기억하도록 하는 코드를 작성해야 합니다.
Page 탐색 간에 소량의 상태를 기억해야 하는 경우에는 FrameworkPropertyMetadata.Journal 메타데이터 플래그로 구성된 종속성 속성(DependencyProperty 참조)을 사용할 수 있습니다.
Page가 탐색 간에 기억해야 하는 상태가 여러 데이터로 구성된 경우에는 하나의 클래스에 상태를 캡슐화하고 IProvideCustomContentState 인터페이스를 구현하는 방법이 코드를 덜 사용하는 방법입니다.
Page 자체에서 외부로 탐색하지 않고 단일 Page의 여러 상태를 탐색해야 하는 경우에는 IProvideCustomContentState 및 NavigationService.AddBackEntry를 사용할 수 있습니다.
쿠키
WPF 응용 프로그램이 데이터를 저장할 수 있는 다른 방법은 SetCookie 및 GetCookie 메서드를 사용하여 만들고, 업데이트하고, 삭제할 수 있는 쿠키를 사용하는 방법입니다. WPF에서 만들 수 있는 쿠키는 다른 유형의 웹 응용 프로그램에 사용되는 쿠키와 같습니다. 쿠키는 응용 프로그램 세션 도중 또는 사이에 응용 프로그램이 클라이언트 시스템에 저장하는 임의의 데이터입니다. 쿠키 데이터는 일반적으로 다음과 같은 이름/값 쌍의 형태를 가집니다.
Name=Value
쿠키를 설정할 위치의 Uri와 함께 데이터가 SetCookie에 전달되면 쿠키가 메모리 내에서 만들어지며 이는 현재 응용 프로그램 세션의 기간 동안에만 사용 가능합니다. 이러한 유형의 쿠키를 세션 쿠키라고 합니다.
응용 프로그램 세션 간에 쿠키를 저장하려면 다음 형식을 사용하여 쿠키에 만료 날짜를 추가해야 합니다.
NAME=VALUE; expires=DAY, DD-MMM-YYYY HH:MM:SS GMT
만료 날짜가 설정된 쿠키는 쿠키가 만료될 때까지 현재 Windows 설치의 Temporary Internet Files 폴더에 저장됩니다. 이러한 쿠키는 응용 프로그램 세션 간에 지속되므로 영구 쿠키라고 합니다.
쿠키가 SetCookie 메서드로 설정된 위치의 Uri를 전달하여 GetCookie 메서드를 호출하면 세션 쿠키와 영구 쿠키를 모두 검색할 수 있습니다.
다음은 WPF에서 쿠키가 지원되는 몇 가지 방법입니다.
WPF 독립 실행형 응용 프로그램과 XBAPs 모두 쿠키를 만들고 관리할 수 있습니다.
XBAP에서 만들어진 쿠키는 브라우저에서 액세스할 수 있습니다.
같은 도메인의 XBAPs는 쿠키를 만들고 공유할 수 있습니다.
같은 도메인의 XBAPs 및 HTML 페이지는 쿠키를 만들고 공유할 수 있습니다.
XBAPs 및 느슨한 XAML 페이지가 웹 요청을 실행하면 쿠키가 디스패치됩니다.
최상위 XBAPs 및 IFRAMES에서 호스팅되는 XBAPs 모두 쿠키에 액세스할 수 있습니다.
WPF에서의 쿠키 지원은 모든 지원 브라우저에 대해 동일합니다.
Internet Explorer에서 쿠키와 관련된 P3P 정책은 특히 자사 및 타사 XBAPs와 관련하여 WPF에 의해 준수됩니다.
구조적 탐색
데이터를 한 Page에서 다른 페이지로 전달해야 하는 경우에는 데이터를 Page의 기본값이 아닌 생성자에 인수로 전달할 수 있습니다. 이 방법을 사용하는 경우에는 Page를 활성 상태로 유지해야 합니다. 그렇지 않으면 다음에 Page를 탐색할 때 WPF에서 기본 생성자를 사용하여 Page를 다시 인스턴스화합니다.
또는 Page는 전달해야 하는 데이터로 설정된 속성을 구현할 수 있습니다. 하지만 Page가 해당 페이지를 탐색한 Page에 다시 데이터를 전달해야 할 경우에는 상항이 복잡해질 수 있습니다. 여기서 문제는 Page에서 탐색한 후 이 페이지로 되돌아오도록 보장하는 메커니즘을 탐색에서 기본적으로 지원하지 않는다는 점입니다. 기본적으로 탐색은 호출/반환 의미를 지원하지 않습니다. 이 문제를 해결하기 위해 WPF는 Page가 예측 가능하고 구조화된 방식으로 반환되도록 하기 위해 사용할 수 있는 PageFunction<T> 클래스를 제공합니다. 자세한 내용은 구조적 탐색 개요를 참조하십시오.
NavigationWindow 클래스
지금까지 탐색 가능한 콘텐츠와 함께 응용 프로그램을 빌드하는 데 많이 사용하는 탐색 서비스에 대한 전반적인 내용을 살펴보았습니다. 이러한 서비스를 XBAPs와 관련하여 살펴보았지만 XBAPs에만 해당되는 것은 아닙니다. 최신 운영 체제와 Windows 응용 프로그램에서는 최근 사용자의 브라우저 환경이 갖는 이점을 활용하여 독립 실행형 응용 프로그램에 브라우저 스타일의 탐색을 통합합니다. 몇 가지 예를 들면 다음과 같습니다.
동의어 사전: 선택한 단어를 탐색합니다.
파일 탐색기: 파일 및 폴더를 탐색합니다.
마법사: 복잡한 작업을 서로 간 탐색할 수 있는 여러 페이지로 나눕니다. Windows 기능의 추가와 제거를 처리하는 Windows 구성 요소 마법사를 예로 들 수 있습니다.
브라우저 스타일의 탐색을 독립 실행형 응용 프로그램에 통합하려면 NavigationWindow 클래스를 사용하면 됩니다. NavigationWindow는 Window에서 파생되며 XBAPs에서 제공하는 탐색 지원 기능을 통해 확장됩니다. NavigationWindow를 독립 실행형 응용 프로그램의 주 창 또는 대화 상자와 같은 보조 창으로 사용할 수 있습니다.
NavigationWindow를 구현하려면 WPF의 최상위 클래스(Window, Page 등)에서처럼 태그와 코드 숨김을 함께 사용합니다. 다음 예제에서 이를 확인할 수 있습니다.
<NavigationWindow
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.MainWindow"
Source="HomePage.xaml"/>
Namespace SDKSample
Partial Public Class MainWindow
Inherits NavigationWindow
Public Sub New()
InitializeComponent()
End Sub
End Class
End Namespace
using System.Windows.Navigation; // NavigationWindow
namespace SDKSample
{
public partial class MainWindow : NavigationWindow
{
public MainWindow()
{
InitializeComponent();
}
}
}
이 코드에서는 NavigationWindow가 열리면 자동으로 Page(HomePage.xaml)를 탐색하는 NavigationWindow를 만듭니다. NavigationWindow가 주 응용 프로그램 창인 경우 StartupUri 특성을 사용하여 창을 시작할 수 있습니다. 다음 태그에서 이를 확인할 수 있습니다.
<Application
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
StartupUri="MainWindow.xaml" />
다음 그림에서는 독립 실행형 응용 프로그램의 주 창인 NavigationWindow를 보여 줍니다.
이전 예제에서 NavigationWindow 구현 코드에 NavigationWindow의 제목을 설정하지 않았지만 그림에서는 제목을 볼 수 있습니다. 이 제목은 다음 코드에서 볼 수 있는 WindowTitle 속성을 사용하여 설정됩니다.
<Page
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
Title="Home Page"
WindowTitle="NavigationWindow">
...
</Page>
WindowWidth 및 WindowHeight 속성을 설정하면 NavigationWindow에도 영향을 미칩니다.
대개의 경우 NavigationWindow의 동작이나 모양을 사용자 지정해야 할 때 이를 자체적으로 구현합니다. 동작이나 모양을 사용자 지정할 필요가 없는 경우에는 바로 가기를 사용할 수 있습니다. Page의 pack URI를 독립 실행형 응용 프로그램에서 StartupUri로 지정하면 Application에서 자동으로 Page를 호스팅할 NavigationWindow를 만듭니다. 다음 태그에서 그 방법을 볼 수 있습니다.
<Application
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
StartupUri="HomePage.xaml" />
대화 상자와 같은 보조 응용 프로그램 창이 NavigationWindow가 되도록 하려면 다음 예제의 코드를 사용하여 해당 창을 열 수 있습니다.
' Open a navigation window as a dialog box
Dim dlg As New NavigationWindowDialogBox()
dlg.Source = New Uri("HomePage.xaml", UriKind.Relative)
dlg.Owner = Me
dlg.ShowDialog()
// Open a navigation window as a dialog box
NavigationWindowDialogBox dlg = new NavigationWindowDialogBox();
dlg.Source = new Uri("HomePage.xaml", UriKind.Relative);
dlg.Owner = this;
dlg.ShowDialog();
다음 그림에서는 앞의 예제를 실행한 결과를 보여 줍니다.
여기서 볼 수 있듯이 NavigationWindow에는 사용자가 저널을 탐색할 수 있는 Internet Explorer 스타일의 Back 및 Forward 단추가 표시됩니다. 이러한 단추는 다음 그림에서처럼 동일한 사용자 환경을 제공합니다.
페이지에서 자체 저널 탐색 지원과 UI를 제공하는 경우에는 ShowsNavigationUI 속성 값을 false로 설정하여 NavigationWindow에서 표시하는 Back 및 Forward 단추를 숨길 수 있습니다.
또는 WPF에서 사용자 지정 지원을 통해 NavigationWindow 자체의 UI를 바꿀 수 있습니다.
Frame 클래스
브라우저와 NavigationWindow는 모두 탐색 가능한 콘텐츠를 호스팅하는 창입니다. 경우에 따라 응용 프로그램에는 전체 창에서 호스팅할 필요가 없는 콘텐츠가 있습니다. 대신, 이러한 콘텐츠는 다른 콘텐츠 안에 호스팅됩니다. Frame 클래스를 사용하면 탐색 가능한 콘텐츠를 다른 콘텐츠 안에 넣을 수 있습니다. Frame은 NavigationWindow 및 XBAPs와 동일한 지원을 제공합니다.
다음 예제에서는 Frame 요소를 사용하여 Frame을 Page에 선언적으로 추가하는 방법을 보여 줍니다.
<Page
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
WindowTitle="Page that Hosts a Frame"
WindowWidth="250"
WindowHeight="250">
...
<Frame Source="FramePage1.xaml" />
...
</Page>
이 태그는 Frame 요소의 Source 특성을 Frame이 처음에 탐색해야 하는 Page에 대한 pack URI로 설정합니다. 다음 그림은 여러 페이지 간에 탐색한 Frame이 추가된 Page가 있는 XBAP를 보여 줍니다.
Frame을 Page의 콘텐츠 안에서만 사용할 수 있는 것은 아닙니다. Frame을 Window의 콘텐츠 안에 호스팅하는 경우도 많습니다.
기본적으로 Frame은 다른 저널이 없는 경우에만 자체 저널을 사용합니다. Frame이 NavigationWindow 또는 XBAP 안에 호스팅되는 콘텐츠의 일부인 경우 Frame은 NavigationWindow 또는 XBAP에 속한 저널을 사용합니다. 하지만 Frame이 자체 저널을 사용해야 하는 경우도 있습니다. 이렇게 하는 이유 중 하나는 Frame에서 호스팅되는 페이지 내에서의 저널 탐색을 허용하기 위한 것입니다. 다음 그림에서 이에 대해 볼 수 있습니다.
이 경우 Frame의 JournalOwnership 속성을 OwnsJournal로 설정하여 자체 저널을 사용하도록 Frame을 구성할 수 있습니다. 다음 태그에서 이를 확인할 수 있습니다.
<Page
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
WindowTitle="Page that Hosts a Frame"
WindowWidth="250"
WindowHeight="250">
...
<Frame Source="FramePage1.xaml" JournalOwnership="OwnsJournal" />
...
</Page>
다음 그림에서는 자체 저널을 사용하는 Frame 안에서 탐색할 때의 영향을 보여 줍니다.
저널 항목이 Internet Explorer에 의해서가 아니라 Frame의 탐색 UI에 의해 표시된다는 점에 유의하십시오.
참고 |
---|
Frame이 Window에서 호스팅되는 콘텐츠의 일부인 경우 Frame은 자체 저널을 사용하므로 자체 탐색 UI를 표시합니다. |
사용자 환경에서 Frame이 탐색 UI를 표시하지 않고 자체 저널을 제공해야 하는 경우에는 NavigationUIVisibility를 Hidden으로 설정하여 탐색 UI를 숨길 수 있습니다. 다음 태그에서 이를 확인할 수 있습니다.
<Page
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
WindowTitle="Page that Hosts a Frame"
WindowWidth="250"
WindowHeight="250">
...
<Frame
Source="FramePage1.xaml"
JournalOwnership="OwnsJournal"
NavigationUIVisibility="Hidden" />
...
</Page>
탐색 호스트
Frame 및 NavigationWindow는 탐색 호스트라고 하는 클래스입니다. 탐색 호스트는 콘텐츠를 탐색하고 표시할 수 있는 클래스입니다. 이를 위해 각 탐색 호스트는 자체 NavigationService 및 저널을 사용합니다. 다음 그림에서 탐색 호스트의 기본 생성을 볼 수 있습니다.
기본적으로 이를 통해 NavigationWindow 및 Frame은 XBAP가 브라우저에서 호스팅될 때 제공하는 것과 같은 탐색 지원을 제공합니다.
NavigationService와 저널을 사용하는 것 이외에도 탐색 호스트는 NavigationService가 구현하는 것과 같은 멤버를 구현합니다. 다음 그림에서 이에 대해 볼 수 있습니다.
따라서 멤버에 대해 직접 탐색 지원을 프로그래밍할 수 있습니다. Window에서 호스팅되는 Frame에 대한 사용자 지정 탐색 UI를 제공해야 하는 경우에 이 방법을 고려할 수 있습니다. 또한 두 유형 모두 각각 백 스택 및 정방향 스택에서 저널 항목을 열거할 수 있는 BackStack(NavigationWindow.BackStack, Frame.BackStack) 및 ForwardStack(NavigationWindow.ForwardStack, Frame.ForwardStack)을 포함한 추가적인 탐색 관련 멤버를 구현합니다.
앞서 말했듯이 응용 프로그램 안에는 둘 이상의 저널이 존재할 수 있습니다. 다음 그림에서는 이러한 경우에 대한 예제를 제공합니다.
XAML 페이지 이외의 콘텐츠 탐색
이 항목 전체에서 Page 및 pack XBAPs를 사용하여 WPF의 다양한 탐색 기능을 소개했습니다. 하지만 응용 프로그램으로 컴파일되는 Page만 탐색할 수 있는 유일한 콘텐츠 형식이 아니며 pack XBAPs만 콘텐츠를 식별하는 유일한 방법이 아닙니다.
이 단원에서 설명했듯이 느슨한 XAML 파일, HTML 파일 및 개체도 탐색할 수 있습니다.
느슨한 XAML 파일 탐색
느슨한 XAML 파일은 다음 특성을 가진 파일입니다.
XAML만 포함됩니다. 즉, 코드가 없습니다.
적절한 네임스페이스 선언이 있습니다.
파일 확장명이 .xaml입니다.
느슨한 XAML 파일인 Person.xaml로 저장되는 다음 콘텐츠를 예로 들어보겠습니다.
<!-- Person.xaml -->
<TextBlock xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation">
<TextBlock FontWeight="Bold">Name:</TextBlock>
<TextBlock>Nancy Davolio</TextBlock>
<LineBreak />
<TextBlock FontWeight="Bold">Favorite Color:</TextBlock>
<TextBlock>Yellow</TextBlock>
</TextBlock>
파일을 두 번 클릭하면 브라우저가 열리고 콘텐츠가 탐색되어 표시됩니다. 다음 그림에서 이를 확인할 수 있습니다.
다음 위치의 느슨한 XAML 파일을 표시할 수 있습니다.
로컬 시스템, 인트라넷 또는 인터넷의 웹 사이트
Universal Naming Convention (UNC) 파일 공유
로컬 디스크
느슨한 XAML 파일은 브라우저의 즐겨찾기에 추가되거나 브라우저의 홈 페이지로 설정될 수 있습니다.
참고 |
---|
느슨한 XAML 페이지의 게시 및 시작에 대한 자세한 내용은 WPF 응용 프로그램 배포(WPF)를 참조하십시오. |
느슨한 XAML과 관련된 한 가지 제한 사항은 부분 신뢰에서 실행하기에 안전한 콘텐츠만 호스팅할 수 있다는 점입니다. 예를 들어 Window는 느슨한 XAML 파일의 루트 요소가 될 수 없습니다. 자세한 내용은 WPF 부분 신뢰 보안을 참조하십시오.
프레임을 사용하여 HTML 파일 탐색
예상할 수 있듯이 HTML도 탐색할 수 있습니다. http 체계를 사용하는 URI를 제공하기만 하면 됩니다. 예를 들어 다음 XAML은 HTML 페이지를 탐색하는 Frame을 보여 줍니다.
<Frame Source="https://www.microsoft.com/default.aspx" />
HTML를 탐색하려면 특별한 권한이 필요합니다. 예를 들어 인터넷 영역 부분 신뢰 보안 샌드박스에서 실행되고 있는 XBAP에서는 탐색할 수 없습니다. 자세한 내용은 WPF 부분 신뢰 보안을 참조하십시오.
WebBrowser 컨트롤을 사용하여 HTML 파일 탐색
WebBrowser 컨트롤에서는 HTML 문서 호스팅, 탐색 및 스크립트/관리 코드 상호 운용성을 지원합니다. WebBrowser 컨트롤에 대한 자세한 내용은 WebBrowser를 참조하십시오.
Frame과 마찬가지로 WebBrowser를 사용하여 HTML을 탐색하려면 별도의 권한이 필요합니다. 예를 들어 부분 신뢰 응용 프로그램에서는 원본 사이트의 HTML만 탐색할 수 있습니다. 자세한 내용은 WPF 부분 신뢰 보안을 참조하십시오.
사용자 지정 개체 탐색
사용자 지정 개체로 저장된 데이터가 있는 경우 이 데이터를 표시하는 한 가지 방법은 이 개체에 바인딩된 콘텐츠가 있는 Page를 만드는 것입니다(데이터 바인딩 개요 참조). 개체를 표시하기 위해 전체 페이지를 만드는 수고를 하지 않으려면 해당 개체를 곧바로 탐색하면 됩니다.
다음 코드에서 구현된 Person 클래스를 살펴보십시오.
Namespace SDKSample
Public Class Person
Private _name As String
Private _favoriteColor As Color
Public Sub New()
End Sub
Public Sub New(ByVal name As String, ByVal favoriteColor As Color)
Me._name = name
Me._favoriteColor = favoriteColor
End Sub
Public Property Name() As String
Get
Return Me._name
End Get
Set(ByVal value As String)
Me._name = value
End Set
End Property
Public Property FavoriteColor() As Color
Get
Return Me._favoriteColor
End Get
Set(ByVal value As Color)
Me._favoriteColor = value
End Set
End Property
End Class
End Namespace
using System.Windows.Media; // Color
namespace SDKSample
{
public class Person
{
string name;
Color favoriteColor;
public Person() { }
public Person(string name, Color favoriteColor)
{
this.name = name;
this.favoriteColor = favoriteColor;
}
public string Name
{
get { return this.name; }
set { this.name = value; }
}
public Color FavoriteColor
{
get { return this.favoriteColor; }
set { this.favoriteColor = value; }
}
}
}
이를 탐색하려면 다음 코드에서처럼 NavigationWindow.Navigate 메서드를 호출합니다.
<Page
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.HomePage"
WindowTitle="Page that Navigates to an Object">
...
<Hyperlink Name="hyperlink" Click="hyperlink_Click">
Navigate to Nancy Davolio
</Hyperlink>
...
</Page>
Namespace SDKSample
Partial Public Class HomePage
Inherits Page
Public Sub New()
InitializeComponent()
End Sub
Private Sub hyperlink_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
Dim person As New Person("Nancy Davolio", Colors.Yellow)
Me.NavigationService.Navigate(person)
End Sub
End Class
End Namespace
using System.Windows; // RoutedEventArgs
using System.Windows.Controls; // Page
using System.Windows.Media; // Colors
namespace SDKSample
{
public partial class HomePage : Page
{
public HomePage()
{
InitializeComponent();
}
void hyperlink_Click(object sender, RoutedEventArgs e)
{
Person person = new Person("Nancy Davolio", Colors.Yellow);
this.NavigationService.Navigate(person);
}
}
}
다음 그림에서는 앞의 예제를 실행한 결과를 보여 줍니다.
이 그림에서는 유용한 내용이 표시되지 않음을 볼 수 있습니다. 사실 표시되는 값은 Person 개체에 대한 ToString 메서드의 반환 값입니다. 기본적으로 WPF가 개체를 나타내기 위해서는 이 값만 사용할 수 있습니다. ToString 메서드를 재정의하여 더 유용한 정보를 반환할 수 있지만 이 경우에도 문자열 값에 한정됩니다. WPF의 표현 기능이 제공하는 장점을 활용할 수 있는 한 가지 방법은 데이터 템플릿을 사용하는 방법입니다. WPF가 특정 형식의 개체와 연결할 수 있는 데이터 템플릿을 구현할 수 있습니다. 다음 코드에서는 Person 개체에 대한 데이터 템플릿을 보여 줍니다.
<Application
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SDKSample"
x:Class="SDKSample.App"
StartupUri="HomePage.xaml">
<Application.Resources>
<!-- Data Template for the Person Class -->
<DataTemplate DataType="{x:Type local:Person}">
<TextBlock xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation">
<TextBlock FontWeight="Bold">Name:</TextBlock>
<TextBlock Text="{Binding Path=Name}" />
<LineBreak />
<TextBlock FontWeight="Bold">Favorite Color:</TextBlock>
<TextBlock Text="{Binding Path=FavoriteColor}" />
</TextBlock>
</DataTemplate>
</Application.Resources>
</Application>
여기에서 데이터 템플릿은 DataType 특성에서 x:Type 태그 확장을 사용하여 Person 형식과 연결됩니다. 그런 다음 데이터 템플릿은 TextBlock 요소(TextBlock 참조)를 Person 클래스의 속성에 바인딩합니다. 다음 그림에서는 Person 개체의 업데이트된 모양을 보여 줍니다.
이 방법의 장점은 데이터 템플릿을 재사용하여 개체를 응용 프로그램의 모든 위치에서 일관되게 표시할 수 있다는 점입니다.
데이터 템플릿에 대한 자세한 내용은 데이터 템플릿 개요를 참조하십시오.
보안
XBAPs는 WPF 탐색 지원을 통해 인터넷에서 탐색할 수 있으며 응용 프로그램이 타사 콘텐츠를 호스팅할 수 있습니다. 응용 프로그램과 사용자가 해로운 동작을 하지 못하도록 하기 위해 WPF는 보안(WPF) 및 WPF 부분 신뢰 보안에서 다루는 여러 보안 기능을 제공합니다.