개발노트

8. [.NET MAUI] INavigation 으로 Page(View) 전환하기 본문

앱 개발/.NET MAUI

8. [.NET MAUI] INavigation 으로 Page(View) 전환하기

mroh1226 2022. 3. 14. 17:44
반응형

MainPage의 Button을 클릭했을 때 새로운 Page(View)로 넘어가는 기능을 구현해보자.

+ 추가로 Page에서 Root Page로 돌아가는 기능도 구현해본다.

 

이 기능을 구현하기 위해서 INavigation이라는 인터페이스가 필요하다.

- INavigation 참고자료

https://docs.microsoft.com/ko-kr/dotnet/api/xamarin.forms.inavigation?view=xamarin-forms

 

INavigation 인터페이스 (Xamarin.Forms)

플랫폼별 탐색을 추상화하는 인터페이스입니다.

docs.microsoft.com

 


1. MainPage_ViewModel.cs 소스에 INavigation을 전역으로 선언한다.

public INavigation MovePage_Navigation { get; set; }

"MovePage_Navigation"으로 선언하였다.

 

 

1-1. MainPage_ViewModel에 INavigation을 매개변수(파라미터)로 받는 생성자를 추가로 작성하고, 그안에 Command Click_Btn10을 아래와 같이 작성한다.

 public MainPage_ViewModel(INavigation navigation)
{
        MovePage_Navigation = navigation; //전역으로 선언한 Navigation에 파라로 받은 값 입력

        Click_Btn10 = new Command(async () => //비동기를 위해 async 
        {               
            await MovePage_Navigation.PushAsync(new Page1()); //비동기식 호출을 대기를 위해 await 
        },
        () =>
        {
         return true;
        });
}

 

Command를 비동기 호출로 작성한다.

- 비동기 동기 호출에 대한 참고자료

 

async 및 await를 사용한 TAP(작업 비동기 프로그래밍) 모델(C#)

C#에서 비동기 프로그래밍에 대한 간소화된 접근 방식인 작업 기반 비동기 프로그래밍을 사용하는 시기 및 방법을 알아봅니다.

docs.microsoft.com

 

 

동기, 비동기 호출에 대해서

영어로는 Synchronous, Asynchronous Call

chanspark.github.io

 


2. MainPage.xaml 마크업 소스에 NavigationPage.TitleView를 추가하여 페이지에 Navigation 제목을 입력해준다.

 

2-1 Button의 Command Property에 ViewModel에 있는 "Click_Btn10" 를 바인딩 시킨다.

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:vm="clr-namespace:AppMaui.ViewModels"
             x:Class="AppMaui.MainPage"
             BackgroundColor="{DynamicResource SecondaryColor}">

    <NavigationPage.TitleView>
        <Label Text="Navigation Title"/>
    </NavigationPage.TitleView>

    <ScrollView>
        <Grid Padding="20,60,20,60"  HorizontalOptions="CenterAndExpand" VerticalOptions="StartAndExpand"
              RowDefinitions="*,*,*,*,*"
              ColumnDefinitions="*,*,*">

            <Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="4" FontSize="Title" 
                   Text="{Binding Row_Column }" />

            <Button Grid.Row="1" Grid.Column="0" Text="1,0" Command="{Binding Click_Btn10}"/>
           

        </Grid>
    </ScrollView>
</ContentPage>

 

 

2-1. MainPage.xaml.cs (MainPage 코드 비하인드)에 BindingContext 부분을 INavigation을 파라로 받는 생성해준 생성자로 수정한다.

using AppMaui.ViewModels;

namespace AppMaui;

public partial class MainPage : ContentPage
{
	public MainPage()
	{
		InitializeComponent();
		BindingContext = new MainPage_ViewModel(Navigation);
	}
}

 


3. Views 디렉토리에 새로운 Page를 추가한다.

.NET MAUI ContentPage (XAML) 추가

 

Page1.xaml 생성된 모습

3-1. Page1.xaml.cs (Page1 코드 비하인드)에도 동일하게 Navigation을 아래와 같이 적용해준다.

using AppMaui.ViewModels;

namespace AppMaui;

public partial class Page1 : ContentPage
{
	public Page1()
	{
		InitializeComponent();
		BindingContext = new Page1_ViewModel(Navigation);
	}
}

 

3-2 Page1(View)의 ViewModel (Page1_ViewModel.cs) 도  추가로 생성한뒤 아래와 같이 작성해준다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AppMaui.Services;
using System.Windows.Input;

namespace AppMaui.ViewModels
{
    class Page1_ViewModel : Notify
    {
        public INavigation nv_BackToMain { get; set; }
        public ICommand cmd_BackToMain { get; set; }
        public Page1_ViewModel()
        {

        } 

        public Page1_ViewModel(INavigation navigation)
        {
            nv_BackToMain = navigation;

            cmd_BackToMain = new Command( () =>
            {
                nv_BackToMain.PopToRootAsync(); //처음 Navigation Root로 돌아가기
            }, () =>
            {
                return true;
            });

        }
    }
}

 

 

3-3 Page1.xaml 마크업 소스도 아래와 같이 작성해준다.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="AppMaui.Page1"
             Title="Page1"
             BackgroundColor="White">
    <NavigationPage.TitleView>
        <Label Text="Page1"/>
    </NavigationPage.TitleView>
    
    
    <StackLayout>
        <Grid RowDefinitions="*,*,*,*" ColumnDefinitions="*,*,*">
            
            <Label Grid.Row="0" Grid.RowSpan="6" Grid.Column="0" Grid.ColumnSpan="3" Text="Label" FontSize="20"/>
            <Button Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="3" Text="BackToMain" Command="{Binding cmd_BackToMain}" />

        </Grid>
    </StackLayout>
</ContentPage>

 


4. 마지막으로 App.Xaml.cs (App.Xaml의 코드 비하인드)에 들어가서 아래와 같이 수정한다.

약 4시간을 허무하게 보낸 이 부분... (이 부분을 수정하지 않더라도 정상 빌드가 되기 때문에 찾기 힘들었다.)

public App()
{
	InitializeComponent();
    
	MainPage = new NavigationPage(new MainPage());
}


이 소스를 수정하지않으면 PushModalAsync 은 동작하지만,(이것도... 새로운 Page가 Stack되기 전에 있는 Page의 컴포넌트가 눌리는 현상이 생김) PushAsync은 동작하지않는다. 


5. 빌드해본다.

 

5-1 MainPage에서 버튼클릭 (Page1으로 이동)

MainPage -> Page1

 

5-2 Page1에서 Root Navigation인 MainPage로 이동

Page1 -> MainPage

 

잘돌아간다.

 

끝!

반응형
Comments