.NET MAUI 앱 만들기
이 자습서 시리즈는 플랫폼 간 코드만 사용하는 .NET 다중 플랫폼 앱 UI(.NET MAUI) 앱을 만드는 방법을 보여 줍니다. 즉, 작성하는 코드는 Windows, Android, iOS 또는 macOS와 관련이 없습니다. 만들 앱은 사용자가 여러 노트를 만들고 저장하고 로드할 수 있는 노트 작성 앱입니다.
이 자습서에서는 다음을 하는 방법을 알아볼 수 있습니다.
- .NET MAUI Shell 앱을 만듭니다.
- 선택한 플랫폼에서 앱을 실행합니다.
- XAML(eXtensible Application Markup Language)을 사용하여 사용자 인터페이스를 정의하고 코드를 통해 XAML 요소와 상호 작용합니다.
- 뷰를 만들고 데이터에 바인딩합니다.
- 탐색을 사용하여 페이지로 이동
Visual Studio 2022를 사용하여 메모를 입력하고 디바이스 스토리지에 저장할 수 있는 애플리케이션을 만듭니다. 최종 애플리케이션은 다음과 같습니다.
프로젝트 만들기
이 자습서를 시작하려면 먼저 첫 번째 앱 빌드 문서를 따라야 합니다. 프로젝트를 만드는 동안 다음 설정을 사용합니다.
프로젝트 이름
이 값은 .로
Notes
설정해야 합니다. 프로젝트의 이름이 다른 경우 이 자습서에서 복사하여 붙여넣는 코드로 인해 빌드 오류가 발생할 수 있습니다.솔루션과 프로젝트를 같은 디렉터리에 배치
이 설정의 선택을 취소합니다.
프로젝트를 만들 때 최신 .NET 프레임워크를 선택합니다.
대상 디바이스 선택
.NET MAUI 앱은 여러 운영 체제 및 디바이스에서 실행되도록 설계되었습니다. 앱을 테스트하고 디버그할 대상을 선택해야 합니다.
Visual Studio 도구 모음의 디버그 대상을 디버그하고 테스트할 장치로 설정합니다. 다음 단계에서는 디버그 대상을 Android로 설정하는 방법을 보여 줍니다.
- 대상 디버그 드롭다운 단추를 선택합니다.
- Android 에뮬레이터 항목을 선택합니다.
- 에뮬레이터 디바이스를 선택합니다.
앱 셸 사용자 지정
Visual Studio에서 .NET MAUI 프로젝트를 만들면 4개의 중요한 코드 파일이 생성됩니다. Visual Studio의 솔루션 탐색기 창에서 볼 수 있습니다.
이러한 파일은 .NET MAUI 앱을 구성하고 실행하는 데 도움이 될 수 있습니다. 각 파일은 아래에 설명된 다른 용도로 사용됩니다.
MauiProgram.cs
앱을 부트스트랩하는 코드 파일입니다. 이 파일의 코드는 앱을 구성하고 시작하는 앱의 플랫폼 간 진입점 역할을 합니다. 템플릿 시작 코드는 App.xaml 파일에서 정의한 클래스를 가리킵니
App
다.App.xaml 및 App.xaml.cs
단순하게 유지하기 위해 두 파일을 모두 단일 파일이라고 합니다. 일반적으로 XAML 파일, .xaml 파일 자체 및 솔루션 탐색기 자식 항목인 해당 코드 파일이 있는 두 개의 파일이 있습니다. .xaml 파일에는 XAML 태그가 포함되고 코드 파일에는 XAML 태그와 상호 작용하기 위해 사용자가 만든 코드가 포함되어 있습니다.
App.xaml 파일에는 색, 스타일 또는 템플릿과 같은 앱 전체 XAML 리소스가 포함되어 있습니다. App.xaml.cs 파일에는 일반적으로 Shell 애플리케이션을 인스턴스화하는 코드가 포함되어 있습니다. 이 프로젝트에서는 클래스를 가리킵니다
AppShell
.AppShell.xaml 및 AppShell.xaml.cs
이 파일은 앱의
AppShell
시각적 계층 구조를 정의하는 데 사용되는 클래스를 정의합니다.MainPage.xaml 및 MainPage.xaml.cs
앱에서 표시하는 시작 페이지입니다. MainPage.xaml 파일은 페이지의 UI(사용자 인터페이스)를 정의합니다. MainPage.xaml.cs 단추 클릭 이벤트에 대한 코드와 같은 XAML에 대한 코드 숨김을 포함합니다.
"정보" 페이지 추가
첫 번째 사용자 지정은 프로젝트에 다른 페이지를 추가하는 것입니다. 이 페이지는 작성자, 버전 및 자세한 정보를 위한 링크와 같은 이 앱에 대한 정보를 나타내는 "정보" 페이지입니다.
Visual Studio의 솔루션 탐색기 창에서 메모 프로젝트> 새 항목 추가...를 마우스 오른쪽 단추로>클릭합니다.
새 항목 추가 대화 상자의 창 왼쪽에 있는 템플릿 목록에서 .NET MAUI를 선택합니다. 다음으로, .NET MAUI ContentPage(XAML) 템플릿을 선택합니다. AboutPage.xaml 파일의 이름을 지정하고 추가를 선택합니다.
AboutPage.xaml 파일은 페이지의 UI를 나타내는 모든 XAML 태그를 표시하는 새 문서 탭을 엽니다. 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="Notes.AboutPage"> <VerticalStackLayout Spacing="10" Margin="10"> <HorizontalStackLayout Spacing="10"> <Image Source="dotnet_bot.png" SemanticProperties.Description="The dot net bot waving hello!" HeightRequest="64" /> <Label FontSize="22" FontAttributes="Bold" Text="Notes" VerticalOptions="End" /> <Label FontSize="22" Text="v1.0" VerticalOptions="End" /> </HorizontalStackLayout> <Label Text="This app is written in XAML and C# with .NET MAUI." /> <Button Text="Learn more..." Clicked="LearnMore_Clicked" /> </VerticalStackLayout> </ContentPage>
Ctrl+S를 누르거나 파일 저장 AboutPage.xaml 메뉴를 선택하여 파일을>저장합니다.
페이지에 배치된 XAML 제어의 주요 부분을 하나씩 살펴봅시다.
<ContentPage>
는 클래스의 루트 개체입니다AboutPage
.<VerticalStackLayout>
는 .의 유일한 자식 개체입니다 ContentPage. ContentPage 는 자식 개체를 하나만 가질 수 있습니다. 형식에는 VerticalStackLayout 여러 자식이 있을 수 있습니다. 이 레이아웃 컨트롤은 자식 요소들을 하나씩 세로로 정렬합니다.<HorizontalStackLayout>
는 자식이 수평으로<VerticalStackLayout>
정렬되는 것을 제외하고는 a와 동일하게 작동합니다.<Image>
는 이미지를 표시합니다. 이 경우 모든 .NET MAUI 프로젝트와 함께 제공되는 이미지를 사용합니다dotnet_bot.png
.Important
프로젝트에 추가된 파일은 실제로
dotnet_bot.svg
.입니다. .NET MAUI는 SVG(확장 가능한 벡터 그래픽) 파일을 대상 디바이스에 따라 PNG(이식 가능한 네트워크 그래픽) 파일로 변환합니다. 따라서 .NET MAUI 앱 프로젝트에 SVG 파일을 추가할 때 확장이 있는 XAML 또는 C#.png
에서 참조해야 합니다. SVG 파일에 대한 유일한 참조는 프로젝트 파일에 있어야 합니다.<Label>
제어는 텍스트를 표시합니다.<Button>
컨트롤은 이벤트를 발생Clicked
시키는 사용자가 누를 수 있습니다.Clicked
이벤트에 대한 응답으로 코드를 실행할 수 있습니다.Clicked="LearnMore_Clicked"
Clicked
단추의 이벤트는 코드 숨김 파일에 정의되는 이벤트 처리기에 할당LearnMore_Clicked
됩니다. 이 코드는 다음 단계에서 만들게 됩니다.
Clicked 이벤트 처리
다음 단계는 단추의 Clicked
이벤트에 대한 코드를 추가하는 것입니다.
Visual Studio의 솔루션 탐색기 창에서 AboutPage.xaml 파일을 확장하여 코드 숨김 파일 AboutPage.xaml.cs 표시합니다. 그런 다음 AboutPage.xaml.cs 파일을 두 번 클릭하여 코드 편집기에서 엽니다.
시스템 브라우저를 특정 URL로 여는 다음
LearnMore_Clicked
이벤트 처리기 코드를 추가합니다.private async void LearnMore_Clicked(object sender, EventArgs e) { // Navigate to the specified URL in the system browser. await Launcher.Default.OpenAsync("https://aka.ms/maui"); }
시스템 브라우저를
async
열 때 키워드를 사용할 수 있도록 메서드 선언에 키워드가await
추가되었습니다.Ctrl+S를 누르거나 파일 저장 AboutPage.xaml.cs 메뉴를 선택하여 파일을>저장합니다.
이제 XAML 및 코드 숨김이 AboutPage
완료되었으므로 앱에 표시되어야 합니다.
이미지 리소스 추가
일부 컨트롤은 이미지를 사용하여 사용자가 앱과 상호 작용하는 방식을 향상시킬 수 있습니다. 이 섹션에서는 iOS에서 사용할 두 개의 대체 이미지와 함께 앱에서 사용할 두 개의 이미지를 다운로드합니다.
다음 이미지를 다운로드합니다.
아이콘: 정보
이 이미지는 이전에 만든 정보 페이지의 아이콘으로 사용됩니다.아이콘: 참고 사항
이 이미지는 이 자습서의 다음 부분에서 만들 노트 페이지의 아이콘으로 사용됩니다.
이미지를 다운로드한 후 파일 탐색기 사용하여 프로젝트의 Resources\Images 폴더로 이동할 수 있습니다. 이 폴더의 모든 파일은 프로젝트에 MauiImage 리소스로 자동으로 포함됩니다. Visual Studio를 사용하여 프로젝트에 이미지를 추가할 수도 있습니다. 이미지를 직접 이동하는 경우 다음 절차를 건너뜁니다.
Important
iOS 관련 이미지 다운로드를 건너뛰지 말고 이 자습서를 완료해야 합니다.
Visual Studio를 사용하여 이미지 이동
Visual Studio의 솔루션 탐색기 창에서 리소스 폴더를 확장하면 이미지 폴더가 표시됩니다.
팁
파일 탐색기 사용하여 이미지를 이미지 폴더 위에 있는 솔루션 탐색기 창으로 직접 끌어서 놓을 수 있습니다. 그러면 파일이 폴더로 자동으로 이동되고 프로젝트에 포함됩니다. 파일을 끌어서 놓기로 선택한 경우 이 절차의 나머지 부분을 무시합니다.
이미지를 마우스 오른쪽 단추로 클릭하고 추가>기존 항목...을 선택합니다.
다운로드한 이미지가 포함된 폴더로 이동합니다.
파일 형식에 대한 필터를 이미지 파일로 변경합니다.
Ctrl 키를 누른 채 다운로드한 각 이미지를 클릭한 다음 추가 키를 누릅니다.
앱 셸 수정
이 문서의 시작 부분에 설명된 대로 클래스는 AppShell
앱의 UI를 만드는 데 사용되는 XAML 태그인 앱의 시각적 계층 구조를 정의합니다. XAML을 업데이트하여 컨트롤을 추가합니다.TabBar
솔루션 탐색기 창에서 AppShell.xaml 파일을 두 번 클릭하여 XAML 편집기를 엽니다. XAML 표시를 다음 코드로 바꿉니다.
<?xml version="1.0" encoding="UTF-8" ?> <Shell x:Class="Notes.AppShell" xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:Notes" Shell.FlyoutBehavior="Disabled"> <TabBar> <ShellContent Title="Notes" ContentTemplate="{DataTemplate local:MainPage}" Icon="{OnPlatform 'icon_notes.png', iOS='icon_notes_ios.png', MacCatalyst='icon_notes_ios.png'}" /> <ShellContent Title="About" ContentTemplate="{DataTemplate local:AboutPage}" Icon="{OnPlatform 'icon_about.png', iOS='icon_about_ios.png', MacCatalyst='icon_about_ios.png'}" /> </TabBar> </Shell>
Ctrl+S를 누르거나 AppShell.xaml 파일 저장 메뉴를 선택하여 파일을>저장합니다.
XAML의 주요 부분을 세분화해 보겠습니다.
<Shell>
는 XAML 태그의 루트 개체입니다.<TabBar>
는 .의 내용입니다 Shell.- 의 내부에 두 개의
<ShellContent>
개체가 있습니다<TabBar>
. 템플릿 코드를 바꾸기 전에 페이지를 가리키는 단일<ShellContent>
개체가MainPage
있었습니다.
및 해당 자식은 TabBar
사용자 인터페이스 요소를 나타내는 것이 아니라 앱의 시각적 계층 구조를 구성합니다. Shell은 이러한 개체를 사용하고 각 페이지를 나타내는 맨 위에 막대가 있는 콘텐츠에 대한 사용자 인터페이스를 생성합니다. 각 페이지의 속성은 ShellContent.Icon
특수 구문을 {OnPlatform ...}
사용합니다. 이 구문은 XAML 페이지가 각 플랫폼에 대해 컴파일될 때 처리되며 이를 통해 각 플랫폼에 대한 속성 값을 지정할 수 있습니다. 이 경우 모든 플랫폼은 기본적으로 아이콘을 icon_about.png
사용하지만 iOS 및 MacCatalyst는 을 사용합니다 icon_about_ios.png
.
각 <ShellContent>
개체는 표시할 페이지를 가리킵니다. 속성에 의해 설정됩니다 ContentTemplate
.
앱 실행
F5 키를 누르거나 Visual Studio 맨 위에 있는 재생 단추를 눌러 앱을 실행합니다.
메모와 정보라는 두 개의 탭이 있습니다. 정보 탭을 누르면 앱이 만든 항목으로 AboutPage
이동합니다. 자세히 알아보기 ... 단추를 눌러 웹 브라우저를 엽니다.
앱을 닫고 Visual Studio로 돌아갑니다. Android 에뮬레이터를 사용하는 경우 가상 디바이스에서 앱을 종료하거나 Visual Studio 맨 위에 있는 중지 단추를 누릅니다.
노트에 대한 페이지 만들기
이제 앱에 및 AboutPage
앱이 MainPage
포함되어 있으므로 나머지 앱 만들기를 시작할 수 있습니다. 먼저 사용자가 메모를 만들고 표시할 수 있는 페이지를 만든 다음 코드를 작성하여 메모를 로드하고 저장합니다.
메모 페이지에 메모가 표시되고 저장하거나 삭제할 수 있습니다. 먼저 프로젝트에 새 페이지를 추가합니다.
Visual Studio의 솔루션 탐색기 창에서 메모 프로젝트> 새 항목 추가...를 마우스 오른쪽 단추로>클릭합니다.
새 항목 추가 대화 상자의 창 왼쪽에 있는 템플릿 목록에서 .NET MAUI를 선택합니다. 다음으로, .NET MAUI ContentPage(XAML) 템플릿을 선택합니다. 파일 이름을 NotePage.xaml로 지정한 다음 추가를 선택합니다.
NotePage.xaml 파일이 새 탭에서 열리고 페이지의 UI를 나타내는 모든 XAML 태그가 표시됩니다. 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="Notes.NotePage" Title="Note"> <VerticalStackLayout Spacing="10" Margin="5"> <Editor x:Name="TextEditor" Placeholder="Enter your note" HeightRequest="100" /> <Grid ColumnDefinitions="*,*" ColumnSpacing="4"> <Button Text="Save" Clicked="SaveButton_Clicked" /> <Button Grid.Column="1" Text="Delete" Clicked="DeleteButton_Clicked" /> </Grid> </VerticalStackLayout> </ContentPage>
Ctrl +S를 누르거나 파일 저장 NotePage.xaml 메뉴를 선택하여 파일을>저장합니다.
페이지에 배치된 XAML 제어의 주요 부분을 하나씩 살펴봅시다.
<VerticalStackLayout>
자식 컨트롤을 세로로 정렬합니다.<Editor>
는 여러 줄 텍스트 편집기 컨트롤이며 내부 첫 번째 컨트롤 VerticalStackLayout입니다.<Grid>
는 레이아웃 컨트롤이며 VerticalStackLayout.이 컨트롤은 셀을 만들 열과 행을 정의합니다. 자식 컨트롤은 해당 셀 내에 배치됩니다.
기본적으로 컨트롤에는 Grid 단일 셀을 만드는 단일 행과 열이 포함됩니다. 열은 너비로 정의되고
*
너비 값은 가능한 한 많은 공간을 채우도록 열에 지시합니다. 이전 코드 조각은 할당된 공간에ColumnDefinitions="*,*"
열을 균등하게 분산하는 가능한 한 많은 공간을 사용하여 두 열을 정의했습니다. 열 크기는 문자로,
구분됩니다.a에 의해 Grid 정의된 열과 행은 0부터 인덱싱됩니다. 따라서 첫 번째 열은 인덱스 0, 두 번째 열은 인덱스 1 등이 됩니다.
두 개의
<Button>
컨트롤이 열 내부에<Grid>
있으며 열이 할당됩니다. 자식 컨트롤이 열 할당을 정의하지 않으면 첫 번째 열에 자동으로 할당됩니다. 이 태그에서 첫 번째 단추는 "저장" 단추이며 첫 번째 열 0에 자동으로 할당됩니다. 두 번째 단추는 "삭제" 단추이며 두 번째 열인 열 1에 할당됩니다.두 단추에
Clicked
이벤트가 처리됩니다. 다음 섹션에서 해당 처리기에 대한 코드를 추가합니다.
메모 로드 및 저장
NotePage.xaml.cs 코드 숨김 파일을 엽니다. 다음 세 가지 방법으로 NotePage.xaml 파일에 대한 코드 숨김을 열 수 있습니다.
- NotePage.xaml이 열려 있고 편집 중인 현재 문서인 경우 F7 키를 누릅니다.
- NotePage.xaml이 열려 있고 편집 중인 현재 문서인 경우 텍스트 편집기를 마우스 오른쪽 단추로 클릭하고 코드 보기를 선택합니다.
- 솔루션 탐색기 사용하여 NotePage.xaml 항목을 확장하여 NotePage.xaml.cs 파일을 표시합니다. 파일을 두 번 클릭하여 엽니다.
새 XAML 파일을 추가하면 코드 숨김에는 생성자에 한 줄, 메서드에 대한 호출이 InitializeComponent
포함됩니다.
namespace Notes;
public partial class NotePage : ContentPage
{
public NotePage()
{
InitializeComponent();
}
}
이 메서드는 InitializeComponent
XAML 태그를 읽고 태그로 정의된 모든 개체를 초기화합니다. 개체는 부모-자식 관계에 연결되고 코드에 정의된 이벤트 처리기는 XAML에서 설정된 이벤트에 연결됩니다.
이제 코드 숨김 파일에 대한 자세한 내용을 이해했으므로 NotePage.xaml.cs 코드 숨김 파일에 코드를 추가하여 노트 로드 및 저장을 처리합니다.
메모를 만들면 디바이스에 텍스트 파일로 저장됩니다. 파일의 이름은 변수로
_fileName
표시됩니다. 클래스에 다음string
변수 선언을NotePage
추가합니다.public partial class NotePage : ContentPage { string _fileName = Path.Combine(FileSystem.AppDataDirectory, "notes.txt");
위의 코드는 파일 경로를 생성하여 앱의 로컬 데이터 디렉터리에 저장합니다. 파일 이름이 notes.txt.
클래스의 생성자에서 메서드가
InitializeComponent
호출된 후 디바이스에서 파일을 읽고 컨트롤의Text
속성에TextEditor
해당 내용을 저장합니다.public NotePage() { InitializeComponent(); if (File.Exists(_fileName)) TextEditor.Text = File.ReadAllText(_fileName); }
다음으로, XAML에 정의된 이벤트를 처리하는
Clicked
코드를 추가합니다.private void SaveButton_Clicked(object sender, EventArgs e) { // Save the file. File.WriteAllText(_fileName, TextEditor.Text); } private void DeleteButton_Clicked(object sender, EventArgs e) { // Delete the file. if (File.Exists(_fileName)) File.Delete(_fileName); TextEditor.Text = string.Empty; }
메서드는
SaveButton_Clicked
컨트롤의 텍스트를 Editor 변수가 나타내는_fileName
파일에 씁니다.메서드는
DeleteButton_Clicked
먼저 변수가 나타내는_fileName
파일을 확인하고, 파일이 있는지 확인하여 삭제합니다. 다음으로 컨트롤 Editor 의 텍스트가 지워집니다.Ctrl +S를 누르거나 파일 저장 NotePage.xaml.cs 메뉴를 선택하여 파일을>저장합니다.
코드 숨김 파일의 최종 코드는 다음과 같습니다.
namespace Notes;
public partial class NotePage : ContentPage
{
string _fileName = Path.Combine(FileSystem.AppDataDirectory, "notes.txt");
public NotePage()
{
InitializeComponent();
if (File.Exists(_fileName))
TextEditor.Text = File.ReadAllText(_fileName);
}
private void SaveButton_Clicked(object sender, EventArgs e)
{
// Save the file.
File.WriteAllText(_fileName, TextEditor.Text);
}
private void DeleteButton_Clicked(object sender, EventArgs e)
{
// Delete the file.
if (File.Exists(_fileName))
File.Delete(_fileName);
TextEditor.Text = string.Empty;
}
}
메모 테스트
이제 메모 페이지가 완료되었으므로 사용자에게 표시할 방법이 필요합니다. AppShell.xaml 파일을 열고 첫 번째 ShellContent 항목을 다음 대신 MainPage
가리키 NotePage
도록 변경합니다.
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="Notes.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:Notes"
Shell.FlyoutBehavior="Disabled">
<TabBar>
<ShellContent
Title="Notes"
ContentTemplate="{DataTemplate local:NotePage}"
Icon="{OnPlatform 'icon_notes.png', iOS='icon_notes_ios.png', MacCatalyst='icon_notes_ios.png'}" />
<ShellContent
Title="About"
ContentTemplate="{DataTemplate local:AboutPage}"
Icon="{OnPlatform 'icon_about.png', iOS='icon_about_ios.png', MacCatalyst='icon_about_ios.png'}" />
</TabBar>
</Shell>
파일을 저장하고 앱을 실행합니다. 입력란에 입력하고 저장 단추를 누릅니다. 앱을 닫고 다시 엽니다. 입력한 메모는 디바이스의 스토리지에서 로드해야 합니다.
UI에 데이터 바인딩 및 페이지 탐색
자습서의 이 부분에서는 보기, 모델 및 앱 내 탐색의 개념을 소개합니다.
자습서의 이전 단계에서 프로젝트에 NotePage
AboutPage
두 페이지를 추가했습니다. 페이지는 데이터 보기를 나타냅니다. " NotePage
참고 데이터"를 표시하는 "보기"이며 AboutPage
"앱 정보 데이터"를 표시하는 "보기"입니다. 이러한 두 보기에는 모두 하드 코딩되거나 포함된 해당 데이터의 모델이 있으며, 뷰에서 데이터 모델을 분리해야 합니다.
뷰에서 모델을 분리하면 어떤 이점이 있나요? 모델을 구현하는 실제 코드에 대한 걱정 없이 모델의 모든 부분을 나타내고 상호 작용하도록 뷰를 디자인할 수 있습니다. 이 작업은 이 자습서의 뒷부분에서 제시할 데이터 바인딩을 사용하여 수행됩니다. 하지만 지금은 프로젝트를 재구성할 수 있습니다.
보기 및 모델 구분
기존 코드를 리팩터링하여 모델을 뷰와 분리합니다. 다음 몇 단계에서는 뷰와 모델이 서로 별도로 정의되도록 코드를 구성합니다.
프로젝트에서 더 이상 필요 없는 MainPage.xaml과 MainPage.xaml.cs를 삭제합니다. 솔루션 탐색기 창에서 MainPage.xaml 관련 항목을 찾아 마우스 오른쪽 단추로 클릭하고 삭제를 선택합니다.
팁
MainPage.xaml 항목을 삭제하면 MainPage.xaml.cs 항목도 삭제 됩니다. MainPage.xaml.cs 삭제되지 않은 경우 마우스 오른쪽 단추로 클릭하고 삭제를 선택합니다.
프로젝트를 마우스 오른쪽 단추로 Notes 클릭하고 새 폴더 추가>를 선택합니다. 폴더 이름을 Models로 지정합니다.
프로젝트를 마우스 오른쪽 단추로 Notes 클릭하고 새 폴더 추가>를 선택합니다. 폴더 이름을 Views로 지정합니다.
NotePage.xaml 항목을 찾아 폴더로 Views 끕니다. NotePage.xaml.cs 함께 이동해야 합니다.
Important
파일을 이동할 때 Visual Studio는 일반적으로 이동 작업에 시간이 오래 걸릴 수 있는 방법에 대한 경고를 표시합니다. 여기서는 문제가 되지 않습니다. 이 경고가 표시되면 [확인]을 누릅니다.
Visual Studio에서 이동된 파일의 네임스페이스를 조정할지 묻는 메시지가 표시될 수도 있습니다. 다음 단계에서 네임스페이스를 변경하려면 [아니요]를 선택합니다.
AboutPage.xaml 항목을 찾아 폴더로 Views 끕니다. AboutPage.xaml.cs 함께 이동해야 합니다.
보기 네임스페이스 업데이트
보기가 폴더로 Views 이동되었으므로 일치하도록 네임스페이스를 업데이트해야 합니다. 페이지의 XAML 및 코드 숨김 파일에 대한 네임스페이스가 로 설정 Notes
됩니다. 이 작업은 .로 업데이트해야 합니다 Notes.Views
.
솔루션 탐색기 창에서 NotePage.xaml 및 AboutPage.xaml을 모두 확장하여 코드 숨김 파일을 표시합니다.
NotePage.xaml.cs 항목을 두 번 클릭하여 코드 편집기를 엽니다. 네임스페이스를 다음으로
Notes.Views
변경합니다.namespace Notes.Views;
AboutPage.xaml.cs 항목에 대해 이전 단계를 반복합니다.
NotePage.xaml 항목을 두 번 클릭하여 XAML 편집기를 엽니다. 이전 네임스페이스는 XAML의
x:Class
코드 숨김 클래스 형식을 정의하는 특성을 통해 참조됩니다. 이 항목은 네임스페이스가 아니라 형식이 있는 네임스페이스입니다.x:Class
값을Notes.Views.NotePage
로 변경합니다.x:Class="Notes.Views.NotePage"
AboutPage.xaml 항목에 대해 이전 단계를 반복하지만 값을 .로
Notes.Views.AboutPage
설정합니다x:Class
.
Shell에서 네임스페이스 참조 수정
AppShell.xaml은 두 개의 탭을 정의합니다. 하나는 탭에 대한 NotesPage
탭이고 다른 하나는 에 대해 AboutPage
정의됩니다. 이제 이 두 페이지를 새 네임스페이스로 이동했으므로 XAML의 형식 매핑이 유효하지 않습니다. 솔루션 탐색기 창에서 AppShell.xaml 항목을 두 번 클릭하여 XAML 편집기에서 엽니다. 다음 코드 조각과 같이 표시됩니다.
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="Notes.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:Notes"
Shell.FlyoutBehavior="Disabled">
<TabBar>
<ShellContent
Title="Notes"
ContentTemplate="{DataTemplate local:NotePage}"
Icon="{OnPlatform 'icon_notes.png', iOS='icon_notes_ios.png', MacCatalyst='icon_notes_ios.png'}" />
<ShellContent
Title="About"
ContentTemplate="{DataTemplate local:AboutPage}"
Icon="{OnPlatform 'icon_about.png', iOS='icon_about_ios.png', MacCatalyst='icon_about_ios.png'}" />
</TabBar>
</Shell>
.NET 네임스페이스는 XML 네임스페이스 선언을 통해 XAML로 가져옵니다. 이전 XAML 태그에서는 루트 요소<Shell>
의 xmlns:local="clr-namespace:Notes"
특성입니다. 동일한 어셈블리에서 .NET 네임스페이스를 가져오기 위해 XML 네임스페이스를 선언하는 형식은 다음과 같습니다.
xmlns:{XML namespace name}="clr-namespace:{.NET namespace}"
따라서 이전 선언은 XML 네임스페이스를 local
.NET 네임스페이스에 매핑합니다 Notes
. 이름을 local
프로젝트의 루트 네임스페이스에 매핑하는 것이 일반적입니다.
XML 네임스페이 local
스를 제거하고 새 네임스페이스를 추가합니다. 이 새 XML 네임스페이스는 .NET 네임스페이스에 Notes.Views
매핑되므로 이름을 지정합니다 views
. 선언은 다음 특성 xmlns:views="clr-namespace:Notes.Views"
과 같이 표시됩니다.
local
XML 네임스페이스는 속성에서 ShellContent.ContentTemplate
사용되었으며, 이 네임스페이스를 .로 views
변경합니다. 이제 XAML은 다음 코드 조각과 같이 표시됩니다.
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="Notes.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:views="clr-namespace:Notes.Views"
Shell.FlyoutBehavior="Disabled">
<TabBar>
<ShellContent
Title="Notes"
ContentTemplate="{DataTemplate views:NotePage}"
Icon="{OnPlatform 'icon_notes.png', iOS='icon_notes_ios.png', MacCatalyst='icon_notes_ios.png'}" />
<ShellContent
Title="About"
ContentTemplate="{DataTemplate views:AboutPage}"
Icon="{OnPlatform 'icon_about.png', iOS='icon_about_ios.png', MacCatalyst='icon_about_ios.png'}" />
</TabBar>
</Shell>
이제 컴파일러 오류 없이 앱을 실행할 수 있어야 하며 모든 것이 이전과 같이 작동해야 합니다.
모델 정의
현재 모델은 메모 및 뷰에 포함된 데이터입니다. 해당 데이터를 나타내는 새 클래스를 만듭니다. 먼저 메모 페이지의 데이터를 나타내는 모델입니다.
솔루션 탐색기 창에서 폴더를 Models 마우스 오른쪽 단추로 클릭하고 클래스 추가>...를 선택합니다.
클래스 이름을 Note.cs 추가 키를 누릅니다.
Note.cs 열고 코드를 다음 코드 조각으로 바꿉다.
namespace Notes.Models; internal class Note { public string Filename { get; set; } public string Text { get; set; } public DateTime Date { get; set; } }
파일을 저장합니다.
다음으로 정보 페이지의 모델을 만듭니다.
솔루션 탐색기 창에서 폴더를 Models 마우스 오른쪽 단추로 클릭하고 클래스 추가>...를 선택합니다.
클래스 이름을 About.cs 추가 키를 누릅니다.
About.cs 열고 코드를 다음 코드 조각으로 바꿉다.
namespace Notes.Models; internal class About { public string Title => AppInfo.Name; public string Version => AppInfo.VersionString; public string MoreInfoUrl => "https://aka.ms/maui"; public string Message => "This app is written in XAML and C# with .NET MAUI."; }
파일을 저장합니다.
업데이트 정보 페이지
정보 페이지는 업데이트할 수 있는 가장 빠른 페이지가 되며, 앱을 실행하고 모델에서 데이터를 로드하는 방법을 확인할 수 있습니다.
솔루션 탐색기 창에서 Views\AboutPage.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" xmlns:models="clr-namespace:Notes.Models" x:Class="Notes.Views.AboutPage"> <ContentPage.BindingContext> <models:About /> </ContentPage.BindingContext> <VerticalStackLayout Spacing="10" Margin="10"> <HorizontalStackLayout Spacing="10"> <Image Source="dotnet_bot.png" SemanticProperties.Description="The dot net bot waving hello!" HeightRequest="64" /> <Label FontSize="22" FontAttributes="Bold" Text="{Binding Title}" VerticalOptions="End" /> <Label FontSize="22" Text="{Binding Version}" VerticalOptions="End" /> </HorizontalStackLayout> <Label Text="{Binding Message}" /> <Button Text="Learn more..." Clicked="LearnMore_Clicked" /> </VerticalStackLayout> </ContentPage>
이전 코드 조각에서 강조 표시된 변경된 줄을 살펴보겠습니다.
xmlns:models="clr-namespace:Notes.Models"
이 줄은
Notes.Models
.NET 네임스페이스를 XML 네임스페이models
스에 매핑합니다.이 속성은
BindingContext
XML 네임스페이스와models:About
개체를Note.Models.About
사용하여 클래스의 인스턴스로 설정 ContentPage 됩니다. XML 특성 대신 속성 요소 구문을 사용하여 설정되었습니다.Important
지금까지는 XML 특성을 사용하여 속성이 설정되었습니다. 속성과 같은 단순 값에 적합합니다
Label.FontSize
. 그러나 속성 값이 더 복잡한 경우 속성 요소 구문을 사용하여 개체를 만들어야 합니다. 속성 집합을 사용하여 레이블을 만드는 다음 예제를FontSize
살펴보겠습니다.<Label FontSize="22" />
속성 요소 구문을 사용하여 동일한
FontSize
속성을 설정할 수 있습니다.<Label> <Label.FontSize> 22 </Label.FontSize> </Label>
세
<Label>
개의 컨트롤에서Text
해당 속성 값이 하드 코드된 문자열에서 바인딩 구문{Binding PATH}
으로 변경되었습니다.{Binding}
구문은 런타임에 처리되므로 바인딩에서 반환된 값이 동적이 될 수 있습니다. 바인딩PATH
할 속성 경로의{Binding PATH}
부분입니다. 속성은 현재 컨트롤의BindingContext
. 컨트롤BindingContext
을 사용하면<Label>
설정되지 않습니다. 컨텍스트는 컨트롤에 의해 설정되지 않은 경우 부모로부터 상속되며, 이 경우 부모 개체 설정 컨텍스트는 루트 개체 ContentPage입니다.이 개체는
BindingContext
모델의 인스턴스About
입니다. 레이블 중 하나의 바인딩 경로는 속성을 속성에Label.Text
About.Title
바인딩합니다.
정보 페이지의 마지막 변경 내용은 웹 페이지를 여는 단추 클릭을 업데이트하는 것입니다. URL은 코드 숨김에서 하드 코딩되었지만 URL은 속성에 있는 BindingContext
모델에서 가져옵니다.
솔루션 탐색기 창에서 Views\AboutPage.xaml.cs 파일을 엽니다.
LearnMore_Clicked
메서드를 다음 코드로 바꿉니다.private async void LearnMore_Clicked(object sender, EventArgs e) { if (BindingContext is Models.About about) { // Navigate to the specified URL in the system browser. await Launcher.Default.OpenAsync(about.MoreInfoUrl); } }
강조 표시된 줄을 보면 코드는 Models.About
형식인지 BindingContext
확인하고 형식인지 확인하여 변수에 about
할당합니다. 문 내의 다음 줄은 if
속성에서 제공하는 URL에 대한 브라우저를 about.MoreInfoUrl
엽니다.
앱을 실행하면 이전과 정확히 동일하게 실행되는 것을 볼 수 있습니다. 모델의 값에 대해 변경하고 브라우저에서 연 UI 및 URL도 어떻게 변경되는지 확인합니다.
메모 업데이트 페이지
이전 섹션에서는 페이지 보기를 about 모델에 바인딩 about 했으며 이제 동일한 작업을 수행하여 뷰를 note note 모델에 바인딩합니다. 그러나 이 경우 모델은 XAML에서 생성되지 않지만 다음 몇 단계의 코드 숨김에서 제공됩니다.
솔루션 탐색기 창에서 Views\NotePage.xaml 파일을 엽니다.
<Editor>
속성을 추가하는 컨트롤을 변경합니다Text
. 속성을 속성에 바인딩합니다<Editor ... Text="{Binding Text}"
.Text
<?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="Notes.Views.NotePage" Title="Note"> <VerticalStackLayout Spacing="10" Margin="5"> <Editor x:Name="TextEditor" Placeholder="Enter your note" Text="{Binding Text}" HeightRequest="100" /> <Grid ColumnDefinitions="*,*" ColumnSpacing="4"> <Button Text="Save" Clicked="SaveButton_Clicked" /> <Button Grid.Column="1" Text="Delete" Clicked="DeleteButton_Clicked" /> </Grid> </VerticalStackLayout> </ContentPage>
코드 숨김에 대한 수정은 XAML보다 더 복잡합니다. 현재 코드는 생성자에서 파일 콘텐츠를 로드한 다음 속성으로 TextEditor.Text
직접 설정합니다. 현재 코드는 다음과 같습니다.
public NotePage()
{
InitializeComponent();
if (File.Exists(_fileName))
TextEditor.Text = File.ReadAllText(_fileName);
}
생성자에서 메모를 로드하는 대신 새 LoadNote
메서드를 만듭니다. 이 메서드는 다음을 수행합니다.
- 파일 이름 매개 변수를 수락합니다.
- 새 메모 모델을 만들고 파일 이름을 설정합니다.
- 파일이 있는 경우 해당 콘텐츠를 모델에 로드합니다.
- 파일이 있는 경우 파일을 만든 날짜로 모델을 업데이트합니다.
BindingContext
페이지의 모델을 설정합니다.
솔루션 탐색기 창에서 Views\NotePage.xaml.cs 파일을 엽니다.
클래스에 다음 메서드를 추가합니다.
private void LoadNote(string fileName) { Models.Note noteModel = new Models.Note(); noteModel.Filename = fileName; if (File.Exists(fileName)) { noteModel.Date = File.GetCreationTime(fileName); noteModel.Text = File.ReadAllText(fileName); } BindingContext = noteModel; }
호출
LoadNote
할 클래스 생성자를 업데이트합니다. 메모의 파일 이름은 앱의 로컬 데이터 디렉터리에 만들 임의로 생성된 이름이어야 합니다.public NotePage() { InitializeComponent(); string appDataPath = FileSystem.AppDataDirectory; string randomFileName = $"{Path.GetRandomFileName()}.notes.txt"; LoadNote(Path.Combine(appDataPath, randomFileName)); }
모든 노트를 나열하는 보기 및 모델 추가
자습서의 이 부분에서는 앱의 마지막 부분인 이전에 만든 모든 노트를 표시하는 보기를 추가합니다.
여러 노트 및 탐색
현재 메모 보기에는 단일 메모가 표시됩니다. 여러 노트를 표시하려면 새 보기 및 모델인 AllNotes를 만듭니다.
- 솔루션 탐색기 창에서 폴더를 Views 마우스 오른쪽 단추로 클릭하고 새 항목 추가>...를 선택합니다.
- 새 항목 추가 대화 상자의 창 왼쪽에 있는 템플릿 목록에서 .NET MAUI를 선택합니다. 다음으로, .NET MAUI ContentPage(XAML) 템플릿을 선택합니다. AllNotesPage.xaml 파일의 이름을 지정하고 추가를 선택합니다.
- 솔루션 탐색기 창에서 폴더를 마우스 오른쪽 단추로 클릭하고 Models 클래스 추가>...를 선택합니다.
- 클래스 이름을 AllNotes.cs 추가 키를 누릅니다.
AllNotes 모델 코딩
새 모델은 여러 노트를 표시하는 데 필요한 데이터를 나타냅니다. 이 데이터는 노트 컬렉션을 나타내는 속성이 됩니다. 컬렉션 ObservableCollection
은 특수 컬렉션입니다. 여러 항목(예: a)을 ListView나열하는 컨트롤이 바인딩 ObservableCollection
되면 두 항목이 함께 작동하여 컬렉션과 동기화된 항목 목록을 자동으로 유지합니다. 목록에서 항목을 추가하면 컬렉션이 업데이트됩니다. 컬렉션에서 항목을 추가하면 컨트롤이 새 항목으로 자동으로 업데이트됩니다.
솔루션 탐색기 창에서 Models\AllNotes.cs 파일을 엽니다.
해당 코드를 다음 코드 조각으로 바꿉니다.
using System.Collections.ObjectModel; namespace Notes.Models; internal class AllNotes { public ObservableCollection<Note> Notes { get; set; } = new ObservableCollection<Note>(); public AllNotes() => LoadNotes(); public void LoadNotes() { Notes.Clear(); // Get the folder where the notes are stored. string appDataPath = FileSystem.AppDataDirectory; // Use Linq extensions to load the *.notes.txt files. IEnumerable<Note> notes = Directory // Select the file names from the directory .EnumerateFiles(appDataPath, "*.notes.txt") // Each file name is used to create a new Note .Select(filename => new Note() { Filename = filename, Text = File.ReadAllText(filename), Date = File.GetLastWriteTime(filename) }) // With the final collection of notes, order them by date .OrderBy(note => note.Date); // Add each note into the ObservableCollection foreach (Note note in notes) Notes.Add(note); } }
이전 코드는 이름이 지정된 Notes
컬렉션을 선언하고 메서드를 LoadNotes
사용하여 디바이스에서 노트를 로드합니다. 이 메서드는 LINQ 확장을 사용하여 데이터를 컬렉션으로 로드, 변환 및 정렬합니다 Notes
.
AllNotes 페이지 디자인
다음으로, AllNotes 모델을 지원하도록 뷰를 디자인해야 합니다.
솔루션 탐색기 창에서 Views\AllNotesPage.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="Notes.Views.AllNotesPage" Title="Your Notes"> <!-- Add an item to the toolbar --> <ContentPage.ToolbarItems> <ToolbarItem Text="Add" Clicked="Add_Clicked" IconImageSource="{FontImage Glyph='+', Color=Black, Size=22}" /> </ContentPage.ToolbarItems> <!-- Display notes in a list --> <CollectionView x:Name="notesCollection" ItemsSource="{Binding Notes}" Margin="20" SelectionMode="Single" SelectionChanged="notesCollection_SelectionChanged"> <!-- Designate how the collection of items are laid out --> <CollectionView.ItemsLayout> <LinearItemsLayout Orientation="Vertical" ItemSpacing="10" /> </CollectionView.ItemsLayout> <!-- Define the appearance of each item in the list --> <CollectionView.ItemTemplate> <DataTemplate> <StackLayout> <Label Text="{Binding Text}" FontSize="22"/> <Label Text="{Binding Date}" FontSize="14" TextColor="Silver"/> </StackLayout> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView> </ContentPage>
이전 XAML에는 다음과 같은 몇 가지 새로운 개념이 도입되었습니다.
속성에
ContentPage.ToolbarItems
.ToolbarItem
여기에 정의된 단추는 일반적으로 페이지 제목을 따라 앱의 맨 위에 표시됩니다. 하지만 플랫폼에 따라 다른 위치에 있을 수 있습니다. 이러한 단추 중 하나를 누르면Clicked
일반 단추처럼 이벤트가 발생합니다.속성은
ToolbarItem.IconImageSource
단추에 표시할 아이콘을 설정합니다. 이 아이콘은 프로젝트에서 정의한 모든 이미지 리소스일 수 있지만 이 예제에서는 이 아이콘이FontImage
사용됩니다. AFontImage
는 글꼴의 단일 문자 모양을 이미지로 사용할 수 있습니다.컨트롤은 CollectionView 항목 컬렉션을 표시하며, 이 경우 모델의
Notes
속성에 바인딩됩니다. 컬렉션 뷰에서 각 항목을 표시하는 방법은 및CollectionView.ItemTemplate
속성을 통해CollectionView.ItemsLayout
설정됩니다.컬렉션
CollectionView.ItemTemplate
의 각 항목에 대해 선언된 XAML을 생성합니다. 이 경우 XAML의BindingContext
컬렉션 항목 자체가 각 개별 메모가 됩니다. 노트의 템플릿은 메모 및Date
속성에 바인딩된 두 개의 레이블을Text
사용합니다.컬렉션 CollectionView 뷰의
SelectionChanged
항목을 선택할 때 발생하는 이벤트를 처리합니다.
뷰에 대한 코드 숨김을 작성하여 노트를 로드하고 이벤트를 처리해야 합니다.
솔루션 탐색기 창에서 보기/AllNotesPage.xaml.cs 파일을 엽니다.
해당 코드를 다음 코드 조각으로 바꿉니다.
namespace Notes.Views; public partial class AllNotesPage : ContentPage { public AllNotesPage() { InitializeComponent(); BindingContext = new Models.AllNotes(); } protected override void OnAppearing() { ((Models.AllNotes)BindingContext).LoadNotes(); } private async void Add_Clicked(object sender, EventArgs e) { await Shell.Current.GoToAsync(nameof(NotePage)); } private async void notesCollection_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (e.CurrentSelection.Count != 0) { // Get the note model var note = (Models.Note)e.CurrentSelection[0]; // Should navigate to "NotePage?ItemId=path\on\device\XYZ.notes.txt" await Shell.Current.GoToAsync($"{nameof(NotePage)}?{nameof(NotePage.ItemId)}={note.Filename}"); // Unselect the UI notesCollection.SelectedItem = null; } } }
이 코드는 생성자를 사용하여 페이지의 모델을 설정합니다 BindingContext
.
OnAppearing
메서드가 기본 클래스에서 재정의됩니다. 페이지가 탐색될 때와 같이 페이지가 표시될 때마다 이 메서드가 자동으로 호출됩니다. 여기에 있는 코드는 모델에 노트를 로드하도록 지시합니다. CollectionView AllNotes 보기에서 노트가 로드 CollectionView 될 때마다 AllNotes 모델의 속성인 ObservableCollection
AllNotes 모델의 Notes
속성에 바인딩되므로 자동으로 업데이트됩니다.
Add_Clicked
처리기는 또 다른 새로운 개념인 탐색을 소개합니다. 앱이 .NET MAUI Shell을 사용하므로 메서드를 호출 Shell.Current.GoToAsync
하여 페이지로 이동할 수 있습니다. 처리기는 키워드를 사용하여 async
선언되므로 탐색할 때 키워드를 await
사용할 수 있습니다. 이 처리기는 NotePage
.
이전 코드 조각의 마지막 코드 조각은 처리기입니다 notesCollection_SelectionChanged
. 이 메서드는 현재 선택한 항목, Note 모델을 사용하고 해당 정보를 사용하여 해당 항목으로 이동합니다 NotePage
. GoToAsync 는 탐색에 URI 문자열을 사용합니다. 이 경우 쿼리 문자열 매개 변수를 사용하여 대상 페이지에서 속성을 설정하는 문자열이 생성됩니다. URI를 나타내는 보간된 문자열은 다음 문자열과 유사하게 표시됩니다.
NotePage?ItemId=path\on\device\XYZ.notes.txt
ItemId=
매개 변수는 메모가 저장된 디바이스의 파일 이름으로 설정됩니다.
Visual Studio는 NotePage.ItemId
속성이 존재하지 않음을 나타낼 수 있으며, 존재하지 않습니다. 다음 단계는 만들 매개 변수에 따라 모델을 로드하도록 뷰를 ItemId
수정 Note 하는 것입니다.
쿼리 문자열 매개 변수
뷰는 Note 쿼리 문자열 매개 변수ItemId
를 지원해야 합니다. 지금 만듭니다.
솔루션 탐색기 창에서 보기/NotePage.xaml.cs 파일을 엽니다.
QueryProperty
쿼리 문자열 속성의 이름과 매핑되는 클래스 속성을 각각 제공하여 키워드에ItemId
ItemId
특성을class
추가합니다.[QueryProperty(nameof(ItemId), nameof(ItemId))] public partial class NotePage : ContentPage
라는
ItemId
새string
속성을 추가합니다. 이 속성은 메서드를LoadNote
호출하여 속성 값을 전달하며, 이 값은 노트의 파일 이름이어야 합니다.public string ItemId { set { LoadNote(value); } }
SaveButton_Clicked
및DeleteButton_Clicked
처리기를 다음 코드로 바꿉니다.private async void SaveButton_Clicked(object sender, EventArgs e) { if (BindingContext is Models.Note note) File.WriteAllText(note.Filename, TextEditor.Text); await Shell.Current.GoToAsync(".."); } private async void DeleteButton_Clicked(object sender, EventArgs e) { if (BindingContext is Models.Note note) { // Delete the file. if (File.Exists(note.Filename)) File.Delete(note.Filename); } await Shell.Current.GoToAsync(".."); }
이제
async
단추가 있습니다. 눌렀으면 페이지의 URI..
를 사용하여 이전 페이지로 다시 이동합니다._fileName
클래스에서 더 이상 사용되지 않으므로 코드 맨 위에서 변수를 삭제합니다.
앱의 시각적 트리 수정
단일 AppShell
노트 페이지를 로드하는 대신 AllPages 보기를 로드해야 합니다. AppShell.xaml 파일을 열고 첫 번째 ShellContent 항목을 다음 대신 NotePage
가리키 AllNotesPage
도록 변경합니다.
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="Notes.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:views="clr-namespace:Notes.Views"
Shell.FlyoutBehavior="Disabled">
<TabBar>
<ShellContent
Title="Notes"
ContentTemplate="{DataTemplate views:AllNotesPage}"
Icon="{OnPlatform 'icon_notes.png', iOS='icon_notes_ios.png', MacCatalyst='icon_notes_ios.png'}" />
<ShellContent
Title="About"
ContentTemplate="{DataTemplate views:AboutPage}"
Icon="{OnPlatform 'icon_about.png', iOS='icon_about_ios.png', MacCatalyst='icon_about_ios.png'}" />
</TabBar>
</Shell>
지금 앱을 실행하면 추가 단추를 누르면 앱이 충돌하고 탐색NotesPage
할 수 없다고 불평하는 것을 알 수 있습니다. 다른 페이지에서 탐색할 수 있는 모든 페이지는 탐색 시스템에 등록해야 합니다. AllNotesPage
및 AboutPage
페이지는 에 선언되어 탐색 시스템에 자동으로 등록됩니다TabBar.
NotesPage
탐색 시스템에 등록합니다.
솔루션 탐색기 창에서 AppShell.xaml.cs 파일을 엽니다.
탐색 경로를 등록하는 선을 생성자에 추가합니다.
namespace Notes; public partial class AppShell : Shell { public AppShell() { InitializeComponent(); Routing.RegisterRoute(nameof(Views.NotePage), typeof(Views.NotePage)); } }
Routing.RegisterRoute
메서드는
- 첫 번째 매개 변수는 등록하려는 URI의 문자열 이름이며, 이 경우 확인된 이름은 .입니다
"NotePage"
. - 두 번째 매개 변수는 탐색할 때
"NotePage"
로드할 페이지의 형식입니다.
이제 앱을 실행할 수 있습니다. 새 노트를 추가하고, 노트 간을 탐색하고, 노트를 삭제해 보세요.
이 자습서의 코드를 살펴보세요. 완료된 프로젝트의 복사본을 다운로드하여 코드를 비교하려면 이 프로젝트를 다운로드합니다.
축하합니다!
.NET MAUI 앱 만들기 자습서를 완료했습니다.
다음 단계
자습서 시리즈의 다음 부분에서는 프로젝트에서 MVVM(model-view-viewmodel) 패턴을 구현하는 방법을 알아봅니다.
다음 링크는 이 자습서에서 배운 몇 가지 개념과 관련된 자세한 정보를 제공합니다.
본 섹션과 관련하여 문제가 있으십니까? 문제가 있으시면 본 섹션을 개선하기 위해 피드백을 제출해 주세요.
.NET MAUI