드디어 .NET
MAUI
의 RC 버전이 나왔습니다.
이전에도 있었는지는 모르겠으나, 적어도 제가 MAUI 발표준비를 했었던 1월까지는 없었던 Shell
이라는 개념이 등장하였습니다.
이 Shell은 Xamarin
에 익숙한 분들이라면 조금 낯선 개념일텐데 이 기능이 무엇을 하는지에 대해 잠깐 알아봅니다.
이 글은 제가 개인적으로 이해한 것에 따르므로, 잘못된 내용이 있으면 자유롭게 피드백 부탁드립니다.
먼저 Shell은 MSDN에 설명이 자세히 나왔있으나 사실 읽어봐도 개념이 잘 와닿지 않습니다.
하지만 내용을 바탕으로 조금 생각해보면 프로그램의 UI에 해당할 수 있는 가장 안쪽을 Shell이라는 개념을 적용하여 그 위에서 페이지를 자유롭게 이동할 수 있는 것은 아닐까 합니다.
일단 기본적인 구성은 FlyoutItem
, TabItem
, ShellContent
3가지가 있습니다.
앞의 두 개는 UI 구성 방법을 Flyout 방식이냐 Tab 방식이냐를 나타낼 뿐이고, 이 중 실제 화면에 표현하는 것은 ShellContent
입니다.
(TabItem
은 Xamarin
의 TabbedPage
와 비슷하지만 아래쪽에 나오는 Route
부분과 차이가 있습니다.)
FlyoutItem
<Shell
x:Class="MyTest.Maui.AppShell"
...>
<FlyoutItem Title="Cats">
<Tab>
<ShellContent ContentTemplate="{DataTemplate views:CatsPage}"
Route="CatsPage"/>
</Tab>
</FlyoutItem>
</Shell>
TabItem
<Shell
x:Class="MyTest.Maui.AppShell"
...>
<TabBar>
<Tab>
<ShellContent ContentTemplate="{DataTemplate views:DogsPage}"
Route="DogsPage" />
</Tab>
</TabBar>
</Shell>
ShellContent
<Shell
x:Class="MyTest.Maui.AppShell"
...
Shell.FlyoutBehavior="Disabled">
<ShellContent
Title="Hello, World!"
ContentTemplate="{DataTemplate local:MyCustomPage}"
Route="MyCustomPage" />
</Shell>
코드로 보면 이렇게 생겼는데 가운데 있는 <Tab />
태그는 생략이 가능합니다.
또한 이를 아래와 같이 섞어서 쓸 수도 있습니다.
<Shell
x:Class="MyTest.Maui.AppShell"
...>
<FlyoutItem Title="Animals" Route="Animals">
<Tab>
<ShellContent ContentTemplate="{DataTemplate views:CatsPage}"
Route="CatsPage"/>
<ShellContent ContentTemplate="{DataTemplate views:DogsPage}"
Route="DogsPage"/>
</Tab>
</FlyoutItem>
<ShellContent
Title="Hello, World!"
ContentTemplate="{DataTemplate local:MyCustomPage}"
Route="MyCustomPage" />
</Shell>
여기서 핵심은 Route
키워드입니다.
Route
는 루트 페이지를 이동하는 가장 쉬운 방법입니다.
기존 Xamarin에서는 루트 페이지가 아래 코드처럼 고정되어 있어 쉽게 바꿀 수 없었습니다.
// 기존 Xamarin
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new MainPage());
}
}
// MAUI
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new AppShell();
}
}
그러나 여기 Shell
을 이용하면 루트 페이지를 굉장히 쉽게 바꿀 수 있습니다.
이때 Route
는 그 경로가 되며 이를 Uri
식으로 사용합니다.
예를들어 위 예제에서는 계층도가 아래와 같이 됩니다.
Animals
CatsPage
DogsPage
MyCustomPage
이를 Uri로 바꾸면 다음과 같습니다.
//Animals
//Animals/CatsPage
//Animals/DogsPage
//MyCustomPage
각 페이지의 이동은 Uri
를 통해 이뤄집니다.
페이지의 이동은 비하인드 코드에서 아래 함수를 이용하면 됩니다.
await (Application.Current.MainView as Shell).Current.GoToAsync("//MyCustomPage");
// 또는
await Shell.Current.GoToAsync("//MyCustomPage");
위에서 사용한 /
기호는 Uri
단위지만 맨 앞에 붙으면 기준점이 달아지는데,
이는 문서를 읽어도(영어도 마찬가지) 아직 정확하게 이해하지는 못했습니다.
다만 절대 경로가 //
로 시작한다는 것만 파악했네요.
이로써 루트 페이지를 이동한 다음 내부에서는 Xamarin처럼 await Navigation.PushAsync(new NextPage())
를 사용할 수 있습니다.
이 경우 자동으로 NavigationPage
형태로 판단하여 아래 그림과 같이 뒤로가기 아이콘이 있는 바가 생깁니다.
마무리
정리하자면 MAUI에 새로 생긴 Shell
은 루트 페이지 변경 및 일반적인 페이지 이동으로 사용할 수 있으며 경로는 Uri
형식을 사용하고 그 위치는 Shell
에 정의된 Depth를 따릅니다.
물론 기존 Xamarin과 같이 페이지를 이동하는 것도 가능합니다.
이로써 제가 이해한 바로는 기존에 App
클래스 내부의 MainView
가 강하게 연결되어 있던 것을 느슨하게 결합할 수 있도록 프로그래밍 적으로 해소한 것으로 보이며, 이는 다양한 시나리오에서 사용이 가능할 것 같습니다.