엔터프라이즈 앱 탐색Enterprise App Navigation

Xamarin.Forms에는 일반적으로 UI 사용 하 여 사용자의 상호 작용 또는 내부 논리 기반 상태 변경으로 인해 앱 자체에서 발생 하는 페이지 탐색에 대 한 지원이 포함 됩니다.Xamarin.Forms includes support for page navigation, which typically results from the user's interaction with the UI or from the app itself as a result of internal logic-driven state changes. 그러나 탐색 다음과 같은 과제를 충족 해야 합니다 (MVVM)-Model-view-viewmodel 패턴을 사용 하는 앱에서 구현 하는 복잡 한 수 있습니다.However, navigation can be complex to implement in apps that use the Model-View-ViewModel (MVVM) pattern, as the following challenges must be met:

  • 뷰 간의 종속성과 밀접 한 결합을 발생 하지 않도록 하는 방법을 사용 하 여 뷰를 탐색할 수를 식별 하는 방법입니다.How to identify the view to be navigated to, using an approach that does not introduce tight coupling and dependencies between views.
  • 뷰를 탐색할 수 인스턴스화되고 초기화 프로세스를 조정 하는 방법.How to coordinate the process by which the view to be navigated to is instantiated and initialized. MVVM을 사용 하 여 뷰와 뷰 모델 인스턴스화되고 보기의 바인딩 컨텍스트를 통해 서로 연결에 필요 합니다.When using MVVM, the view and view model need to be instantiated and associated with each other via the view's binding context. 앱 종속성 주입 컨테이너를 사용 하는 뷰와 뷰 모델의 인스턴스화를 특정 생성 메커니즘이 필요할 수도 있습니다.When an app is using a dependency injection container, the instantiation of views and view models might require a specific construction mechanism.
  • 보기 중심 탐색을 수행 하거나 모델 첫 탐색 보려면 여부입니다.Whether to perform view-first navigation, or view model-first navigation. 보기 중심 탐색을 사용 하 여 이동할 페이지 뷰 유형의 이름을 가리킵니다.With view-first navigation, the page to navigate to refers to the name of the view type. 탐색 하는 동안 지정 된 보기가 인스턴스화될에 해당 하는 보기 모델 및 다른 종속 서비스와 함께 합니다.During navigation, the specified view is instantiated, along with its corresponding view model and other dependent services. 대 안으로 이동할 페이지 보기 모델 형식의 이름으로 참조 하는 위치에 보기 모델 첫 탐색을 사용 하는 것입니다.An alternative approach is to use view model-first navigation, where the page to navigate to refers to the name of the view model type.
  • 하는 방법을 명확 하 게 보기 및 보기 모델에서 앱의 탐색 동작을 구분 합니다.How to cleanly separate the navigational behavior of the app across the views and view models. MVVM 패턴은 앱의 UI 프레젠테이션 및 비즈니스 논리 간의 분리를 제공합니다.The MVVM pattern provides a separation between the app's UI and its presentation and business logic. 그러나 앱의 탐색 동작은 앱의 UI 및 프레젠테이션 부분에 걸쳐 경우가 많습니다.However, the navigation behavior of an app will often span the UI and presentations parts of the app. 사용자는 종종는 뷰에서 탐색 시작한 뷰 탐색의 결과로 바뀝니다.The user will often initiate navigation from a view, and the view will be replaced as a result of the navigation. 그러나 탐색 해야 할 수 종종 세션을 시작 하거나 보기 모델 내에서 조정 합니다.However, navigation might often also need to be initiated or coordinated from within the view model.
  • 초기화를 위해 탐색 하는 동안 매개 변수를 전달 하는 방법입니다.How to pass parameters during navigation for initialization purposes. 예를 들어 사용자가 주문 세부 정보를 업데이트 하는 뷰를 탐색 하는 경우 주문 데이터를 올바른 데이터를 표시할 수 있도록 보기로 전달 해야 합니다.For example, if the user navigates to a view to update order details, the order data will have to be passed to the view so that it can display the correct data.
  • 특정 비즈니스 규칙 맞는 되도록 좌표 탐색 방법입니다.How to co-ordinate navigation, to ensure that certain business rules are obeyed. 예를 들어, 사용자 제출 하거나 보기 내에서 수행 된 모든 데이터 변경 내용을 취소 하 라는 메시지가 표시 될 하거나 잘못 된 데이터를 수정할 수 있도록 보기에서 탐색 하기 전에 라는 메시지가 나타날 수 있습니다.For example, users might be prompted before navigating away from a view so that they can correct any invalid data or be prompted to submit or discard any data changes that were made within the view.

이 장에서 제공 하 여 이러한 문제를 해결할는 NavigationService 보기 모델 첫 번째 페이지 탐색 하는 데 사용 되는 클래스입니다.This chapter addresses these challenges by presenting a NavigationService class that's used to perform view model-first page navigation.

참고

NavigationService 사용한만 ContentPage 인스턴스 간의 계층 탐색을 수행 하는 앱은 설계 되었습니다.The NavigationService used by the app is designed only to perform hierarchical navigation between ContentPage instances. 다른 페이지 형식 사이 탐색 하는 서비스를 사용 하 여 예기치 않은 동작이 발생할 수 있습니다.Using the service to navigate between other page types might result in unexpected behavior.

탐색 논리 뷰의 코드 숨김에 상주 하거나 데이터에서 뷰 모델을 바인딩할 수 있습니다.Navigation logic can reside in a view's code-behind, or in a data bound view model. 뷰에서 탐색 논리를 배치 가장 간단한 방법일 수 있습니다, 단위 테스트를 통해 쉽게 테스트할 수는 없습니다.While placing navigation logic in a view might be the simplest approach, it is not easily testable through unit tests. 모델 클래스 단위 테스트를 통해 논리를 실행할 수 있습니다 의미 보기에서 탐색 논리를 배치 합니다.Placing navigation logic in view model classes means that the logic can be exercised through unit tests. 또한 뷰 모델은 특정 비즈니스 규칙 적용 되도록 컨트롤 탐색 논리를 구현한 다음 수 있습니다.In addition, the view model can then implement logic to control navigation to ensure that certain business rules are enforced. 예를 들어, 앱 수 없습니다 없이 첫 번째 페이지를 나 가려고 할 입력 한 데이터가 유효한 지 확인 합니다.For example, an app might not allow the user to navigate away from a page without first ensuring that the entered data is valid.

NavigationService 클래스 테스트 용이성을 승격 하려면 보기 모델에서 일반적으로 호출 됩니다.A NavigationService class is typically invoked from view models, to promote testability. 그러나 모델 보기에서에서 뷰로 이동 하 여 참조 뷰 및 활성 뷰 모델을 사용 하 여, 권장 되지 않습니다 연관 되지 않은 뷰 특히 모델 보기를 필요 합니다.However, navigating to views from view models would require the view models to reference views, and particularly views that the active view model isn't associated with, which is not recommended. 따라서는 NavigationService 표시 여기 뷰 모델 형식은 이동할 대상으로 지정 합니다.Therefore, the NavigationService presented here specifies the view model type as the target to navigate to.

EShopOnContainers 모바일 앱 사용을 NavigationService 클래스 보기 모델 첫 탐색을 제공 합니다.The eShopOnContainers mobile app uses the NavigationService class to provide view model-first navigation. 이 클래스에서 구현 된 INavigationService 다음 코드 예제에 나와 있는 인터페이스:This class implements the INavigationService interface, which is shown in the following code example:

public interface INavigationService  
{  
    ViewModelBase PreviousPageViewModel { get; }  
    Task InitializeAsync();  
    Task NavigateToAsync<TViewModel>() where TViewModel : ViewModelBase;  
    Task NavigateToAsync<TViewModel>(object parameter) where TViewModel : ViewModelBase;  
    Task RemoveLastFromBackStackAsync();  
    Task RemoveBackStackAsync();  
}

이 인터페이스는 다음 메서드를 제공 하는 구현 클래스를 지정 합니다.This interface specifies that an implementing class must provide the following methods:

메서드Method 용도Purpose
InitializeAsync 앱을 실행 하는 경우 두 페이지 중 하나에 대 한 탐색을 수행 합니다.Performs navigation to one of two pages when the app is launched.
NavigateToAsync 지정된 된 페이지에 대 한 계층적 탐색을 수행합니다.Performs hierarchical navigation to a specified page.
NavigateToAsync(parameter) 매개 변수 전달, 지정된 된 페이지에 대 한 계층적 탐색을 수행 합니다.Performs hierarchical navigation to a specified page, passing a parameter.
RemoveLastFromBackStackAsync 탐색 스택에서 이전 페이지를 제거합니다.Removes the previous page from the navigation stack.
RemoveBackStackAsync 탐색 스택에서 모든 이전 페이지를 제거합니다.Removes all the previous pages from the navigation stack.

또한 합니다 INavigationService 인터페이스를 구현 하는 클래스를 제공 하는 지정 된 PreviousPageViewModel 속성.In addition, the INavigationService interface specifies that an implementing class must provide a PreviousPageViewModel property. 이 탐색 스택의 이전 페이지와 관련 된 뷰 모델 유형을 반환 합니다.This property returns the view model type associated with the previous page in the navigation stack.

참고

INavigationService 인터페이스는 일반적으로 지정할 수도 GoBackAsync 프로그래밍 방식으로 탐색 스택의 이전 페이지로 반환 하는 데 사용 되는 메서드.An INavigationService interface would usually also specify a GoBackAsync method, which is used to programmatically return to the previous page in the navigation stack. 그러나이 방법은 eShopOnContainers 모바일 앱에서 누락 된 때문에 필요는 없습니다.However, this method is missing from the eShopOnContainers mobile app because it's not required.

NavigationService 인스턴스 만들기Creating the NavigationService Instance

합니다 NavigationService 클래스를 구현 하는 INavigationService 인터페이스, 다음 코드 예제에서 설명한 것 처럼 Autofac 종속성 주입 컨테이너를 사용 하 여 단일 항목으로 등록 하는:The NavigationService class, which implements the INavigationService interface, is registered as a singleton with the Autofac dependency injection container, as demonstrated in the following code example:

builder.RegisterType<NavigationService>().As<INavigationService>().SingleInstance();

합니다 INavigationService 인터페이스에서 해결 되었습니다는 ViewModelBase 클래스 생성자에 다음 코드 예제에서 설명한 것 처럼:The INavigationService interface is resolved in the ViewModelBase class constructor, as demonstrated in the following code example:

NavigationService = ViewModelLocator.Resolve<INavigationService>();

에 대 한 참조를 반환 하는이 NavigationService 하 여 만든 Autofac 종속성 주입 컨테이너에 저장 된 개체를 InitNavigation 에서 메서드를 App 클래스.This returns a reference to the NavigationService object that's stored in the Autofac dependency injection container, which is created by the InitNavigation method in the App class. 자세한 내용은 탐색할 때 앱이 시작 될합니다.For more information, see Navigating When the App is Launched.

ViewModelBase 저장소 클래스를 NavigationService 의 인스턴스를 NavigationService 형식의 속성 INavigationService합니다.The ViewModelBase class stores the NavigationService instance in a NavigationService property, of type INavigationService. 따라서 모든 보기 모델 클래스에서 파생 되는 합니다 ViewModelBase 클래스를 사용할 수는 NavigationService 속성으로 지정 된 메서드에 액세스할 수는 INavigationService 인터페이스입니다.Therefore, all view model classes, which derive from the ViewModelBase class, can use the NavigationService property to access the methods specified by the INavigationService interface. 삽입의 오버 헤드를 방지 하는이 NavigationService 보기 모델 클래스 각 Autofac 종속성 주입 컨테이너에서 개체입니다.This avoids the overhead of injecting the NavigationService object from the Autofac dependency injection container into each view model class.

탐색 요청 처리Handling Navigation Requests

Xamarin.Forms는 제공 된 NavigationPage 사용자가 앞으로 및 뒤로 필요에 따라 페이지를 통해 이동할 수 있는 계층적 탐색 환경을 구현 하는 클래스입니다.Xamarin.Forms provides the NavigationPage class, which implements a hierarchical navigation experience in which the user is able to navigate through pages, forwards and backwards, as desired. 계층적 탐색에 대한 자세한 내용은 계층적 탐색을 참조하세요.For more information about hierarchical navigation, see Hierarchical Navigation.

사용 하지 않고는 NavigationPage 클래스를 직접 eShopOnContainers 앱 래핑하는 NavigationPage 클래스는 CustomNavigationView 클래스에 다음 코드 예제에 표시 된 대로:Rather than use the NavigationPage class directly, the eShopOnContainers app wraps the NavigationPage class in the CustomNavigationView class, as shown in the following code example:

public partial class CustomNavigationView : NavigationPage  
{  
    public CustomNavigationView() : base()  
    {  
        InitializeComponent();  
    }  

    public CustomNavigationView(Page root) : base(root)  
    {  
        InitializeComponent();  
    }  
}

스타일의 편의 위해이 래핑 목적은 합니다 NavigationPage 클래스에 대 한 XAML 파일 내에서 인스턴스.The purpose of this wrapping is for ease of styling the NavigationPage instance inside the XAML file for the class.

탐색 중 하나를 호출 하 여 뷰 모델 클래스 내에서 수행 되는 NavigateToAsync 에 다음 코드 예제에서 설명한 것 처럼 탐색 중인 페이지에 대 한 뷰 모델 유형을 지정 하는 메서드:Navigation is performed inside view model classes by invoking one of the NavigateToAsync methods, specifying the view model type for the page being navigated to, as demonstrated in the following code example:

await NavigationService.NavigateToAsync<MainViewModel>();

다음 코드 예제는 NavigateToAsync 에서 제공 하는 메서드는 NavigationService 클래스:The following code example shows the NavigateToAsync methods provided by the NavigationService class:

public Task NavigateToAsync<TViewModel>() where TViewModel : ViewModelBase  
{  
    return InternalNavigateToAsync(typeof(TViewModel), null);  
}  

public Task NavigateToAsync<TViewModel>(object parameter) where TViewModel : ViewModelBase  
{  
    return InternalNavigateToAsync(typeof(TViewModel), parameter);  
}

파생 되는 모든 보기 모델 클래스를 사용 하는 각 메서드는 ViewModelBase 를 호출 하 여 계층적 탐색을 수행 하는 클래스는 InternalNavigateToAsync 메서드.Each method allows any view model class that derives from the ViewModelBase class to perform hierarchical navigation by invoking the InternalNavigateToAsync method. 또한 두 번째 NavigateToAsync 메서드를 사용 하면 탐색 데이터를 탐색 중인, 일반적으로 사용 된 초기화를 수행 하는 보기 모델에 전달 되는 인수로 지정 해야 합니다.In addition, the second NavigateToAsync method enables navigation data to be specified as an argument that's passed to the view model being navigated to, where it's typically used to perform initialization. 자세한 내용은 매개 변수 중 탐색 전달합니다.For more information, see Passing Parameters During Navigation.

InternalNavigateToAsync 메서드 탐색 요청을 실행 하 고 다음 코드 예제에 표시 됩니다.The InternalNavigateToAsync method executes the navigation request, and is shown in the following code example:

private async Task InternalNavigateToAsync(Type viewModelType, object parameter)  
{  
    Page page = CreatePage(viewModelType, parameter);  

    if (page is LoginView)  
    {  
        Application.Current.MainPage = new CustomNavigationView(page);  
    }  
    else  
    {  
        var navigationPage = Application.Current.MainPage as CustomNavigationView;  
        if (navigationPage != null)  
        {  
            await navigationPage.PushAsync(page);  
        }  
        else  
        {  
            Application.Current.MainPage = new CustomNavigationView(page);  
        }  
    }  

    await (page.BindingContext as ViewModelBase).InitializeAsync(parameter);  
}  

private Type GetPageTypeForViewModel(Type viewModelType)  
{  
    var viewName = viewModelType.FullName.Replace("Model", string.Empty);  
    var viewModelAssemblyName = viewModelType.GetTypeInfo().Assembly.FullName;  
    var viewAssemblyName = string.Format(  
                CultureInfo.InvariantCulture, "{0}, {1}", viewName, viewModelAssemblyName);  
    var viewType = Type.GetType(viewAssemblyName);  
    return viewType;  
}  

private Page CreatePage(Type viewModelType, object parameter)  
{  
    Type pageType = GetPageTypeForViewModel(viewModelType);  
    if (pageType == null)  
    {  
        throw new Exception($"Cannot locate page type for {viewModelType}");  
    }  

    Page page = Activator.CreateInstance(pageType) as Page;  
    return page;  
}

합니다 InternalNavigateToAsync 첫 번째 호출 하 여 보기 모델에 대 한 탐색을 수행 하는 메서드를 CreatePage 메서드.The InternalNavigateToAsync method performs navigation to a view model by first calling the CreatePage method. 이 메서드는 지정 된 뷰 모델 형식에 해당 하 고 만들고이 뷰 형식의 인스턴스를 반환 하는 뷰를 찾습니다.This method locates the view that corresponds to the specified view model type, and creates and returns an instance of this view type. 보기 모델 형식에 해당 하는 뷰를 찾기는 가정 하는 규칙 기반 접근 방식을 사용 합니다.Locating the view that corresponds to the view model type uses a convention-based approach, which assumes that:

  • 뷰는 뷰 모델 형식으로 동일한 어셈블리에 있습니다.Views are in the same assembly as view model types.
  • 보기에는 합니다. 뷰 자식 네임 스페이스입니다.Views are in a .Views child namespace.
  • 모델 보기에는 합니다. Viewmodel 자식 네임 스페이스입니다.View models are in a .ViewModels child namespace.
  • 뷰 이름은 "Model" 제거를 사용 하 여 모델 이름을 보려면 해당 합니다.View names correspond to view model names, with "Model" removed.

뷰를 인스턴스화할 때 정책이 해당 하는 보기 모델에 연결 합니다.When a view is instantiated, it's associated with its corresponding view model. 이 발생 하는 방법에 대 한 자세한 내용은 참조 하세요. 자동으로 보기 모델 로케이터를 사용 하 여 뷰 모델을 만들기합니다.For more information about how this occurs, see Automatically Creating a View Model with a View Model Locator.

뷰 생성 되는 경우는 LoginView의 새 인스턴스 내에서 래핑된를 CustomNavigationView 클래스 및 할당 합니다 Application.Current.MainPage 속성.If the view being created is a LoginView, it's wrapped inside a new instance of the CustomNavigationView class and assigned to the Application.Current.MainPage property. 이 고, 그렇지를 CustomNavigationView 인스턴스는 검색 하 고는 null이 아닌, 제공 합니다 PushAsync 탐색 스택으로 만들어지는 보기를 적용할 메서드가 실행 됩니다.Otherwise, the CustomNavigationView instance is retrieved, and provided that it isn't null, the PushAsync method is invoked to push the view being created onto the navigation stack. 그러나 경우 검색 CustomNavigationView 인스턴스가 null, 만들어지는 보기의 새 인스턴스 내에서 래핑된 합니다 CustomNavigationView 클래스 및 할당할는 Application.Current.MainPage 속성입니다.However, If the retrieved CustomNavigationView instance is null, the view being created is wrapped inside a new instance of the CustomNavigationView class and assigned to the Application.Current.MainPage property. 이 메커니즘을 이용 하면 탐색 도중 되도록, 페이지에 추가 됩니다 올바르게 탐색 스택에서 비어 있는 경우와 데이터를 포함 하는 경우.This mechanism ensures that during navigation, pages are added correctly to the navigation stack both when it's empty, and when it contains data.

페이지를 캐시 하는 것이 좋습니다.Consider caching pages. 현재 표시 되지 않는 뷰에 대 한 메모리 사용 결과 캐시 하는 페이지입니다.Page caching results in memory consumption for views that are not currently displayed. 그러나 페이지 캐싱을 사용 하지 않고 XAML 구문 분석 하 고 페이지와 해당 하는 보기 모델의 생성 될 때마다 새 페이지를 탐색, 복잡 한 페이지에 대 한 성능 영향을 줄 수 있는 발생할 수 있는 것이 의미가 있습니다.However, without page caching it does mean that XAML parsing and construction of the page and its view model will occur every time a new page is navigated to, which can have a performance impact for a complex page. 잘 디자인 된 페이지의 컨트롤을 너무 많이 사용 하지 않는 경우 성능 충분 해야 합니다.For a well-designed page that does not use an excessive number of controls, the performance should be sufficient. 그러나 페이지 캐싱 도움이 느린 페이지 로드 시간이 발생 하는 경우.However, page caching might help if slow page loading times are encountered.

뷰를 만들고 탐색 한 후의 InitializeAsync 보기의 관련된 보기 모델의 메서드를 실행 합니다.After the view is created and navigated to, the InitializeAsync method of the view's associated view model is executed. 자세한 내용은 매개 변수 중 탐색 전달합니다.For more information, see Passing Parameters During Navigation.

앱을 실행 하는 경우는 InitNavigation 의 메서드는 App 클래스에서 호출 됩니다.When the app is launched, the InitNavigation method in the App class is invoked. 다음 코드 예제에서는 이 메서드를 보여줍니다.The following code example shows this method:

private Task InitNavigation()  
{  
    var navigationService = ViewModelLocator.Resolve<INavigationService>();  
    return navigationService.InitializeAsync();  
}

메서드를 만듭니다 NavigationService Autofac 종속성 주입 컨테이너에서 개체를 호출 하기 전에 대 한 참조를 반환 하 고 해당 InitializeAsync 메서드.The method creates a new NavigationService object in the Autofac dependency injection container, and returns a reference to it, before invoking its InitializeAsync method.

참고

때를 INavigationService 하 여 인터페이스를 해결 합니다 ViewModelBase 클래스 컨테이너 참조를 반환 합니다.를 NavigationService InitNavigation 메서드가 호출 될 때 생성 된 개체.When the INavigationService interface is resolved by the ViewModelBase class, the container returns a reference to the NavigationService object that was created when the InitNavigation method is invoked.

다음 코드 예제는 NavigationService InitializeAsync 메서드:The following code example shows the NavigationService InitializeAsync method:

public Task InitializeAsync()  
{  
    if (string.IsNullOrEmpty(Settings.AuthAccessToken))  
        return NavigateToAsync<LoginViewModel>();  
    else  
        return NavigateToAsync<MainViewModel>();  
}

MainView 앱에 인증에 사용 되는 캐시 된 액세스 토큰을 사용 하는 경우 탐색 합니다.The MainView is navigated to if the app has a cached access token, which is used for authentication. 이 고, 그렇지는 LoginView 가 탐색 됩니다.Otherwise, the LoginView is navigated to.

Autofac 종속성 주입 컨테이너에 대 한 자세한 내용은 참조 하세요. 종속성 주입 소개합니다.For more information about the Autofac dependency injection container, see Introduction to Dependency Injection.

탐색 하는 동안 매개 변수 전달Passing Parameters During Navigation

중 하나를 NavigateToAsync 지정한 메서드는 INavigationService 인터페이스를 탐색 데이터를 탐색 중인, 일반적으로 사용 된 초기화를 수행 하는 보기 모델에 전달 되는 인수로 서 지정 합니다.One of the NavigateToAsync methods, specified by the INavigationService interface, enables navigation data to be specified as an argument that's passed to the view model being navigated to, where it's typically used to perform initialization.

예를 들어 합니다 ProfileViewModel 클래스를 포함를 OrderDetailCommand 에서 순서를 선택할 때 실행 되는 ProfileView 페이지.For example, the ProfileViewModel class contains an OrderDetailCommand that's executed when the user selects an order on the ProfileView page. 실행이 차례로 OrderDetailAsync 메서드를 다음 코드 예제에 나와 있는:In turn, this executes the OrderDetailAsync method, which is shown in the following code example:

private async Task OrderDetailAsync(Order order)  
{  
    await NavigationService.NavigateToAsync<OrderDetailViewModel>(order);  
}

이 메서드 호출에 대 한 탐색 합니다 OrderDetailViewModel전달를 Order 순서에서 선택한 사용자를 나타내는 인스턴스는 ProfileView 페이지입니다.This method invokes navigation to the OrderDetailViewModel, passing an Order instance that represents the order that the user selected on the ProfileView page. 경우는 NavigationService 클래스를 만듭니다를 OrderDetailView, OrderDetailViewModel 클래스를 인스턴스화하고 뷰의 할당할 BindingContext 합니다.When the NavigationService class creates the OrderDetailView, the OrderDetailViewModel class is instantiated and assigned to the view's BindingContext. 로 이동한 후는 OrderDetailView, InternalNavigateToAsync 메서드가 실행 되는 InitializeAsync 뷰의 메서드 보기 모델의 연결 된.After navigating to the OrderDetailView, the InternalNavigateToAsync method executes the InitializeAsync method of the view's associated view model.

합니다 InitializeAsync 에 정의 된 메서드는 ViewModelBase 재정의할 수 있는 메서드로 클래스입니다.The InitializeAsync method is defined in the ViewModelBase class as a method that can be overridden. 이 메서드는 object 탐색 작업을 하는 동안 보기 모델에 전달할 데이터를 나타내는 인수입니다.This method specifies an object argument that represents the data to be passed to a view model during a navigation operation. 탐색 작업에서 데이터를 수신 하는 보기 모델 클래스의 자체 구현을 제공 하는 따라서는 InitializeAsync 필수 초기화를 수행 하는 방법입니다.Therefore, view model classes that want to receive data from a navigation operation provide their own implementation of the InitializeAsync method to perform the required initialization. 다음 코드 예제는 InitializeAsync 메서드에서 OrderDetailViewModel 클래스:The following code example shows the InitializeAsync method from the OrderDetailViewModel class:

public override async Task InitializeAsync(object navigationData)  
{  
    if (navigationData is Order)  
    {  
        ...  
        Order = await _ordersService.GetOrderAsync(  
                        Convert.ToInt32(order.OrderNumber), authToken);  
        ...  
    }  
}

이 메서드를 검색 합니다 Order 에서 탐색 작업을 하는 동안 보기 모델에 전달 된 전체 순서를 검색 하는 데 사용 하는 인스턴스 세부 정보는 OrderService 인스턴스.This method retrieves the Order instance that was passed into the view model during the navigation operation, and uses it to retrieve the full order details from the OrderService instance.

동작을 사용 하 여 호출 탐색Invoking Navigation using Behaviors

탐색은 일반적으로 사용자 상호 작용 하 여 보기에서 트리거됩니다.Navigation is usually triggered from a view by a user interaction. 예를 들어를 LoginView 성공적으로 인증을 수행 하는 탐색을 수행 합니다.For example, the LoginView performs navigation following successful authentication. 다음 코드 예제에서는 탐색 동작에 의해 호출 하는 방법을 보여 줍니다.The following code example shows how the navigation is invoked by a behavior:

<WebView ...>  
    <WebView.Behaviors>  
        <behaviors:EventToCommandBehavior  
            EventName="Navigating"  
            EventArgsConverter="{StaticResource WebNavigatingEventArgsConverter}"  
            Command="{Binding NavigateCommand}" />  
    </WebView.Behaviors>  
</WebView>

런타임 시 합니다 EventToCommandBehavior 와 상호 작용에 응답할 합니다 WebView 합니다.At runtime, the EventToCommandBehavior will respond to interaction with the WebView. 경우는 WebView 웹 페이지로 이동 합니다 Navigating 이벤트가 발생 하 고 실행 하는 NavigateCommand 에서 LoginViewModel.When the WebView navigates to a web page, the Navigating event will fire, which will execute the NavigateCommand in the LoginViewModel. 기본적으로 이벤트에 대 한 이벤트 인수는 명령에 전달 됩니다.By default, the event arguments for the event are passed to the command. 에 지정 된 변환기에서 원본과 대상 간에 전달 될 때이 데이터를 변환 하는 EventArgsConverter 반환 하는 속성을 Url 에서 WebNavigatingEventArgs 합니다.This data is converted as it's passed between source and target by the converter specified in the EventArgsConverter property, which returns the Url from the WebNavigatingEventArgs. 따라서 경우 합니다 NavigationCommand 는 실행, 웹 페이지의 Url 매개 변수로 전달 되는 등록 된 Action합니다.Therefore, when the NavigationCommand is executed, the Url of the web page is passed as a parameter to the registered Action.

차례로 합니다 NavigationCommand 실행을 NavigateAsync 메서드를 다음 코드 예제에 나와 있는:In turn, the NavigationCommand executes the NavigateAsync method, which is shown in the following code example:

private async Task NavigateAsync(string url)  
{  
    ...          
    await NavigationService.NavigateToAsync<MainViewModel>();  
    await NavigationService.RemoveLastFromBackStackAsync();  
    ...  
}

이 메서드 호출에 대 한 탐색 합니다 MainViewModel, 탐색, 다음 제거를 LoginView 페이지 탐색 스택에서.This method invokes navigation to the MainViewModel, and following navigation, removes the LoginView page from the navigation stack.

확인 또는 탐색을 취소 합니다.Confirming or Cancelling Navigation

앱은 사용자를 확인 하거나 탐색을 취소할 수 있도록 탐색 작업을 하는 동안 사용자 상호 작용 해야 합니다.An app might need to interact with the user during a navigation operation, so that the user can confirm or cancel navigation. 예를 들어 사용자가 데이터 입력 페이지를 완벽 하 게 완료 하기 전에 이동 하려고 할 때이 방법을 필요한 수 있습니다.This might be necessary, for example, when the user attempts to navigate before having fully completed a data entry page. 이 경우 앱 사용자가 페이지를 나 가려고 하거나 발생 하기 전에 탐색 작업을 취소할 수 있도록 알림을 제공 해야 합니다.In this situation, an app should provide a notification that allows the user to navigate away from the page, or to cancel the navigation operation before it occurs. 이 탐색은 호출 여부를 제어 하는 알림 응답을 사용 하 여 보기 모델 클래스에서 구현할 수 있습니다.This can be achieved in a view model class by using the response from a notification to control whether or not navigation is invoked.

요약Summary

Xamarin.Forms에는 일반적으로 UI 사용 하 여 사용자의 상호 작용 또는 내부 논리 기반 상태 변경으로 인해 앱 자체에서 발생 하는 페이지 탐색에 대 한 지원이 포함 됩니다.Xamarin.Forms includes support for page navigation, which typically results from the user's interaction with the UI, or from the app itself, as a result of internal logic-driven state changes. 그러나 탐색 MVVM 패턴을 사용 하는 앱에서 구현 복잡할 수 있습니다.However, navigation can be complex to implement in apps that use the MVVM pattern.

제공이 장에서 NavigationService 모델 보기에서에서 보기 모델 첫 탐색 하는 데 사용 되는 클래스입니다.This chapter presented a NavigationService class, which is used to perform view model-first navigation from view models. 보기에서 탐색 논리를 배치 하면 모델 클래스를 통해 자동화 된 테스트 논리를 실행할 수 있습니다 의미 합니다.Placing navigation logic in view model classes means that the logic can be exercised through automated tests. 또한 뷰 모델은 특정 비즈니스 규칙 적용 되도록 컨트롤 탐색 논리를 구현한 다음 수 있습니다.In addition, the view model can then implement logic to control navigation to ensure that certain business rules are enforced.