다음을 통해 공유


구조적 탐색 개요

XBAP(XAML 브라우저 애플리케이션)에서 호스트될 수 있는 콘텐츠인 Frame 또는 NavigationWindow는 팩 URI(Uniform Resource Identifier)로 식별할 수 있고 하이퍼링크로 이동할 수 있는 페이지로 구성됩니다. 하이퍼링크를 통해 정의되는 페이지 및 페이지 탐색 방법의 구조를 탐색 토폴로지라고 합니다. 이 토폴로지는 다양한 애플리케이션 형식, 특히 문서를 탐색하는 애플리케이션에 적합합니다. 해당 애플리케이션의 경우 한쪽 페이지가 다른 페이지에 대해 아무것도 알 필요 없이 사용자가 페이지 사이에서 이동할 수 있습니다.

하지만 다른 유형의 애플리케이션 형식에는 페이지를 탐색할 때 알아야 하는 페이지가 있습니다. 예를 들어 조직의 모든 직원을 나열하는 하나의 "직원 목록" 페이지가 있는 인사 관리 애플리케이션을 살펴보겠습니다. 이 페이지에서 사용자는 하이퍼링크를 클릭하여 새 직원을 추가할 수 있습니다. 클릭되면 페이지가 "직원 추가" 페이지로 이동하여 새 직원의 세부 정보를 수집하고 이를 "직원 목록" 페이지로 반환하여 새 직원을 만들고 목록을 업데이트합니다. 이 탐색 스타일은 처리를 수행하고 값을 반환하는 구조적 프로그래밍이라고 알려진 메서드 호출과 비슷합니다. 마찬가지로 이 탐색 스타일을 구조적 탐색이라고 합니다.

Page 클래스는 구조적 탐색에 대한 지원을 구현하지 않습니다. 대신에 PageFunction<T> 클래스는 Page에서 파생되고 구조적 탐색에 필요한 기본 구문을 사용하여 기능을 확장합니다. 이 항목에서는 PageFunction<T>를 사용하여 구조적 탐색을 설정하는 방법을 보여줍니다.

구조적 탐색

구조적 탐색에서 한 페이지가 다른 페이지를 호출하면 다음 동작의 일부 또는 전체가 필요합니다.

  • 호출 페이지는 호출된 페이지로 이동하고 필요한 경우 호출된 페이지에 필요한 매개 변수를 전달합니다.

  • 사용자가 호출 페이지 사용을 마치면 호출된 페이지는 필요한 경우 특별히 호출 페이지로 돌아갑니다.

    • 호출 페이지가 완료된 방식을 설명하는 상태 정보 반환(예: 사용자가 [확인] 단추나 [취소] 단추를 눌렀는지 여부).

    • 사용자로부터 수집된 데이터 반환(예: 새 직원 세부 정보).

  • 호출 페이지가 호출된 페이지로 돌아가면 호출된 페이지 인스턴스를 다른 인스턴스와 격리하기 위해 호출된 페이지가 탐색 기록에서 제거됩니다.

다음 그림에서는 이러한 동작을 설명합니다.

호출 페이지와 호출된 페이지 사이의 흐름을 보여주는 스크린샷.

PageFunction<T>을 호출된 페이지로 사용하여 이러한 동작을 구현할 수 있습니다.

PageFunction을 사용한 구조적 탐색

이 항목에서는 단일 PageFunction<T>을 사용한 구조적 탐색의 기본 메커니즘을 구현하는 방법을 보여줍니다. 이 샘플에서 PagePageFunction<T>를 호출하여 사용자로부터 String 값을 가져와 반환합니다.

호출 페이지 만들기

PageFunction<T>를 호출하는 페이지는 Page 또는 PageFunction<T>일 수 있습니다. 이 예제에서는 다음 코드와 같이 Page입니다.

<Page 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="StructuredNavigationSample.CallingPage"
    WindowTitle="Calling Page" 
    WindowWidth="250" WindowHeight="150">
</Page>
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;

namespace StructuredNavigationSample
{
    public partial class CallingPage : Page
    {
        public CallingPage()
        {
            InitializeComponent();
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Navigation

Namespace StructuredNavigationSample

Public Class CallingPage
    Inherits Page
    Public Sub New()
        Me.InitializeComponent()
}
End Sub
    }
}
End Class

End Namespace

호출할 페이지 함수 만들기

호출 페이지는 호출된 페이지를 사용하여 사용자로부터 데이터를 수집하고 반환할 수 있으므로 PageFunction<T>은 호출된 페이지가 반환할 값 형식을 형식 인수로 지정하는 제네릭 클래스로 구현됩니다. 다음 코드에서는 String을 반환하는 PageFunction<T>을 사용하여 호출된 페이지의 초기 구현을 보여줍니다.

<PageFunction
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:sys="clr-namespace:System;assembly=mscorlib" 
    x:Class="StructuredNavigationSample.CalledPageFunction"
    x:TypeArguments="sys:String"
    Title="Page Function" 
    WindowWidth="250" WindowHeight="150">

  <Grid Margin="10">

    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="Auto" />
      <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
      <RowDefinition Height="Auto" />
      <RowDefinition />
    </Grid.RowDefinitions>

    <!-- Data -->
    <Label Grid.Column="0" Grid.Row="0">DataItem1:</Label>
    <TextBox Grid.Column="1" Grid.Row="0" Name="dataItem1TextBox"></TextBox>

    <!-- Accept/Cancel buttons -->
    <TextBlock Grid.Column="1" Grid.Row="1" HorizontalAlignment="Right">
      <Button Name="okButton" IsDefault="True" MinWidth="50">OK</Button>
      <Button Name="cancelButton" IsCancel="True" MinWidth="50">Cancel</Button>
    </TextBlock>

  </Grid>

</PageFunction>
using System;
using System.Windows;
using System.Windows.Navigation;

namespace StructuredNavigationSample
{
    public partial class CalledPageFunction : PageFunction<String>
    {
        public CalledPageFunction()
        {
            InitializeComponent();
        }
Imports System.Windows
Imports System.Windows.Navigation

Namespace StructuredNavigationSample

Public Class CalledPageFunction
    Inherits PageFunction(Of String)
    Public Sub New()
        Me.InitializeComponent()
    End Sub
    }
}
End Class

End Namespace

PageFunction<T> 선언은 형식 인수가 추가된 Page 선언과 비슷합니다. 코드 예제에서 확인할 수 있는 것처럼 형식 인수는 x:TypeArguments 특성을 사용하는 XAML 마크업과 표준 일반 형식 인수 구문을 사용하는 코드 숨김 모두에 지정됩니다.

.NET Framework 클래스만 형식 인수로 사용할 필요는 없습니다. PageFunction<T>를 호출하여 사용자 지정 형식으로 추상화되는 도메인별 데이터를 수집할 수 있습니다. 다음 코드에서는 사용자 지정 형식을 PageFunction<T>에 대한 형식 인수로 사용하는 방법을 보여줍니다.

namespace SDKSample
{
    public class CustomType
    {
Public Class CustomType
    }
}
End Class
<PageFunction
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:SDKSample" 
    x:Class="SDKSample.CustomTypePageFunction"
    x:TypeArguments="local:CustomType">
</PageFunction>
using System.Windows.Navigation;

namespace SDKSample
{
    public partial class CustomTypePageFunction : PageFunction<CustomType>
    {
Partial Public Class CustomTypePageFunction
    Inherits System.Windows.Navigation.PageFunction(Of CustomType)
    }
}
End Class

PageFunction<T>에 대한 형식 인수는 다음 섹션의 설명처럼 호출 페이지와 호출된 페이지 간 통신을 위한 기반을 제공합니다.

살펴보겠지만 PageFunction<T> 선언을 통해 식별된 형식은 PageFunction<T>에서 호출 페이지로 데이터를 반환할 때 중요한 역할을 합니다.

PageFunction 호출 및 매개 변수 전달

페이지를 호출하기 위해 호출 페이지는 호출된 페이지를 인스턴스화하고 Navigate 메서드를 사용하여 호출된 페이지로 이동합니다. 이렇게 하면 호출 페이지가 호출된 페이지에서 수집되는 데이터의 기본값과 같은 초기 데이터를 호출된 페이지에 전달할 수 있습니다.

다음 코드에서는 매개 변수가 없는 생성자를 사용하여 호출 페이지에서 매개 변수를 허용하는 호출된 페이지를 보여줍니다.

using System;
using System.Windows;
using System.Windows.Navigation;

namespace StructuredNavigationSample
{
    public partial class CalledPageFunction : PageFunction<String>
    {
Imports System.Windows
Imports System.Windows.Navigation

Namespace StructuredNavigationSample

Public Class CalledPageFunction
    Inherits PageFunction(Of String)
public CalledPageFunction(string initialDataItem1Value)
{
    InitializeComponent();

Public Sub New(ByVal initialDataItem1Value As String)
    Me.InitializeComponent()
    // Set initial value
    this.dataItem1TextBox.Text = initialDataItem1Value;
}
    ' Set initial value
    Me.dataItem1TextBox.Text = initialDataItem1Value
End Sub
    }
}
End Class

End Namespace

다음 코드에서는 호출된 페이지를 인스턴스화하고 여기에 초기 문자열 값을 전달하도록 HyperlinkClick 이벤트를 처리하는 호출 페이지를 보여줍니다.

<Hyperlink Name="pageFunctionHyperlink">Call Page Function</Hyperlink>
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;

namespace StructuredNavigationSample
{
    public partial class CallingPage : Page
    {
        public CallingPage()
        {
            InitializeComponent();
            this.pageFunctionHyperlink.Click += new RoutedEventHandler(pageFunctionHyperlink_Click);
        }
        void pageFunctionHyperlink_Click(object sender, RoutedEventArgs e)
        {

            // Instantiate and navigate to page function
            CalledPageFunction CalledPageFunction = new CalledPageFunction("Initial Data Item Value");
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Navigation

Namespace StructuredNavigationSample

Public Class CallingPage
    Inherits Page
    Public Sub New()
        Me.InitializeComponent()
        AddHandler Me.pageFunctionHyperlink.Click, New RoutedEventHandler(AddressOf Me.pageFunctionHyperlink_Click)
    End Sub
    Private Sub pageFunctionHyperlink_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
}
End Sub
    }
}
End Class

End Namespace

매개 변수를 호출된 페이지로 전달할 필요는 없습니다. 대신에 다음을 수행할 수 있습니다.

  • 호출 페이지에서:

    1. 매개 변수가 없는 생성자를 사용하여 호출된 PageFunction<T>을 인스턴스화합니다.

    2. 매개 변수를 Properties에 저장합니다.

    3. 호출된 PageFunction<T>으로 이동합니다.

  • 호출된 PageFunction<T>에서:

    • Properties에 저장된 매개 변수를 검색하고 사용합니다.

그러나 간단히 살펴보겠지만 호출된 페이지에서 반환된 데이터를 수집하려고 호출된 페이지를 인스턴스화하고 여기로 이동하는 데는 코드를 사용해야 합니다. 이러한 이유로 PageFunction<T>은 활성 상태로 유지되어야 합니다. 그렇지 않으면 다음 번에 PageFunction<T>으로 이동할 때 WPF가 매개 변수가 없는 생성자를 사용하여 PageFunction<T>을 인스턴스화합니다.

하지만 호출된 페이지는 호출 페이지에서 검색될 수 있는 데이터를 반환해야 합니다.

작업에서 호출 페이지로 작업 결과 및 작업 데이터 반환

사용자가 [확인] 또는 [취소] 단추를 눌러 이 예제에서 보여 준 호출된 페이지 사용을 마치면 호출된 페이지가 반환해야 합니다. 호출 페이지는 호출된 페이지를 사용하여 사용자로부터 데이터를 수집했으므로 호출 페이지에는 두 가지 정보가 필요합니다.

  1. 사용자가 호출된 페이지를 취소했는지 여부(이 예제에서 [확인] 또는 [취소] 단추를 눌러). 이 경우 호출 페이지는 호출 페이지가 사용자로부터 수집한 데이터를 처리할지 결정할 수 있습니다.

  2. 사용자가 제공한 데이터.

정보를 반환하기 위해 PageFunction<T>OnReturn 메서드를 구현합니다. 다음 코드에서는 메서드를 호출하는 방법을 보여 줍니다.

using System;
using System.Windows;
using System.Windows.Navigation;

namespace StructuredNavigationSample
{
    public partial class CalledPageFunction : PageFunction<String>
    {
Imports System.Windows
Imports System.Windows.Navigation

Namespace StructuredNavigationSample

Public Class CalledPageFunction
    Inherits PageFunction(Of String)
        void okButton_Click(object sender, RoutedEventArgs e)
        {
            // Accept when Ok button is clicked
            OnReturn(new ReturnEventArgs<string>(this.dataItem1TextBox.Text));
        }

        void cancelButton_Click(object sender, RoutedEventArgs e)
        {
            // Cancel
            OnReturn(null);
        }
    }
}
    Private Sub okButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        ' Accept when Ok button is clicked
        Me.OnReturn(New ReturnEventArgs(Of String)(Me.dataItem1TextBox.Text))
    End Sub

    Private Sub cancelButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        ' Cancel
        Me.OnReturn(Nothing)
    End Sub
End Class

End Namespace

이 예제에서 사용자가 [취소] 단추를 누르면 null 값이 호출 페이지로 반환됩니다. [확인] 단추를 누르면 사용자가 제공한 문자열 값이 반환됩니다. OnReturn은 데이터를 호출 페이지로 반환하기 위해 호출하는 protected virtual 메서드입니다. 데이터는 Result가 반환하는 값의 형식을 형식 인수로 지정하는 제네릭 ReturnEventArgs<T> 형식의 인스턴스로 패키지되어야 합니다. 이 방법으로 특정 형식 인수를 사용하여 PageFunction<T>을 선언하면 PageFunction<T>이 형식 인수로 지정된 형식의 인스턴스를 반환하도록 지정하는 것입니다. 이 예제에서 형식 인수 및 이에 따른 반환 값은 String 형식입니다.

OnReturn이 호출되면 호출 페이지는 PageFunction<T>의 반환 값을 수신하는 어떤 방법이 필요합니다. 이러한 이유로 PageFunction<T>은 호출 페이지에서 처리할 Return 이벤트를 구현합니다. OnReturn이 호출되면 Return이 발생하므로 호출 페이지는 알림을 받기 위해 Return에 등록할 수 있습니다.

using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;

namespace StructuredNavigationSample
{
    public partial class CallingPage : Page
    {
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Navigation

Namespace StructuredNavigationSample

Public Class CallingPage
    Inherits Page
        void pageFunctionHyperlink_Click(object sender, RoutedEventArgs e)
        {

            // Instantiate and navigate to page function
            CalledPageFunction CalledPageFunction = new CalledPageFunction("Initial Data Item Value");
            CalledPageFunction.Return += pageFunction_Return;
            this.NavigationService.Navigate(CalledPageFunction);
        }
        void pageFunction_Return(object sender, ReturnEventArgs<string> e)
        {
            this.pageFunctionResultsTextBlock.Visibility = Visibility.Visible;

            // Display result
            this.pageFunctionResultsTextBlock.Text = (e != null ? "Accepted" : "Canceled");

            // If page function returned, display result and data
            if (e != null)
            {
                this.pageFunctionResultsTextBlock.Text += "\n" + e.Result;
            }
        }
    }
}
    Private Sub pageFunctionHyperlink_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        ' Instantiate and navigate to page function
        Dim calledPageFunction As New CalledPageFunction("Initial Data Item Value")
        AddHandler calledPageFunction.Return, New ReturnEventHandler(Of String)(AddressOf Me.calledPageFunction_Return)
        MyBase.NavigationService.Navigate(calledPageFunction)
    End Sub
    Private Sub calledPageFunction_Return(ByVal sender As Object, ByVal e As ReturnEventArgs(Of String))

        Me.pageFunctionResultsTextBlock.Visibility = Windows.Visibility.Visible

        ' Display result
        Me.pageFunctionResultsTextBlock.Text = IIf((Not e Is Nothing), "Accepted", "Canceled")

        ' If page function returned, display result and data
        If (Not e Is Nothing) Then
            Me.pageFunctionResultsTextBlock.Text = (Me.pageFunctionResultsTextBlock.Text & ChrW(10) & e.Result)
        End If

    End Sub
End Class

End Namespace

작업이 완료될 때 작업 페이지 제거

호출된 페이지가 반환하고 사용자가 호출된 페이지를 취소하면 호출 페이지는 사용자가 제공한 데이터와 호출된 페이지에서 반환된 데이터를 처리합니다. 이 방법으로 데이터를 취득하는 것은 격리된 활동입니다. 호출된 페이지가 반환할 경우 호출 페이지는 추가 데이터를 캡처하기 위해 새 호출 페이지를 만들고 여기로 이동해야 합니다.

하지만 호출된 페이지가 업무 일지에서 제거되지 않는 한 사용자는 호출 페이지의 이전 인스턴스로 돌아갈 수 있습니다. PageFunction<T>이 업무 일지에 유지되는지 여부는 RemoveFromJournal 속성에 따라 결정됩니다. 기본적으로 페이지 함수는 OnReturn이 호출될 때 자동으로 제거됩니다. RemoveFromJournaltrue로 설정되어 있기 때문입니다. OnReturn이 호출된 후 페이지 함수를 탐색 기록에 유지하려면 RemoveFromJournalfalse로 설정합니다.

기타 구조적 탐색 유형

이 항목에서는 구조적 탐색 호출/반환을 지원하기 위해 PageFunction<T>을 사용하는 가장 기본적인 방법을 보여줍니다. 이 기본 사항은 더 복잡한 구조적 탐색을 만들 수 있는 기능을 제공합니다.

예를 들어 사용자로부터 충분한 데이터를 수집하거나 작업을 수행하기 위해 호출 페이지에 여러 페이지가 필요한 경우가 있습니다. 여러 페이지를 사용하는 것을 "마법사"라고 합니다.

다른 경우에는 구조적 탐색을 기반으로 효과적으로 작동하는 복잡한 탐색 토폴로지가 애플리케이션에 포함될 수 있습니다. 자세한 내용은 탐색 토폴로지 개요를 참조하세요.

참고 항목