Xamarin.Forms 빠른 시작 심층 분석

Xamarin.Forms 빠른 시작에서 Notes 애플리케이션이 빌드되었습니다. 이 문서에서는 Xamarin.Forms Shell 애플리케이션의 기본적 작동 원리를 이해하기 위해 빌드된 애플리케이션을 검토합니다.

Visual Studio 소개

Visual Studio는 코드를 솔루션프로젝트로 구성합니다. 솔루션은 하나 이상의 프로젝트를 포함할 수 있는 컨테이너입니다. 프로젝트는 애플리케이션, 지원 라이브러리, 테스트 애플리케이션 등이 될 수 있습니다. Notes 애플리케이션은 다음 스크린샷처럼 3개의 프로젝트를 포함하는 솔루션 하나로 구성됩니다.

Visual Studio Solution Explorer

프로젝트는 다음과 같습니다.

  • Notes - 이 프로젝트는 모든 공유 코드와 공유 UI를 보관하는 .NET Standard 라이브러리 프로젝트입니다.
  • Notes.Android - 이 프로젝트는 Android 관련 코드를 보관하며 Android 애플리케이션의 진입점입니다.
  • Notes.iOS - 이 프로젝트는 iOS 관련 코드를 보관하며 iOS 애플리케이션의 진입점입니다.

Xamarin.Forms 애플리케이션 분석

다음 스크린샷은 Visual Studio의 Notes .NET Standard 라이브러리 프로젝트 콘텐츠를 보여줍니다.

Phoneword .NET Standard Project Contents

프로젝트에는 NuGetSDK 노드를 포함하는 종속성 노드가 있습니다.

  • NuGet - 프로젝트에 추가된 Xamarin.Forms, Xamarin.Essentials, Newtonsoft.Json 및 sqlite-net-pcl NuGet 패키지입니다.
  • SDK - .NET Standard를 정의하는 NuGet 패키지의 전체 집합을 참조하는 NETStandard.Library 메타패키지입니다.

Mac용 Visual Studio 소개

Mac용 Visual Studio는 코드를 솔루션프로젝트로 구성하는 Visual Studio 연습을 따릅니다. 솔루션은 하나 이상의 프로젝트를 포함할 수 있는 컨테이너입니다. 프로젝트는 애플리케이션, 지원 라이브러리, 테스트 애플리케이션 등이 될 수 있습니다. Notes 애플리케이션은 다음 스크린샷처럼 3개의 프로젝트를 포함하는 솔루션 하나로 구성됩니다.

Visual Studio for Mac Solution Pane

프로젝트는 다음과 같습니다.

  • Notes - 이 프로젝트는 모든 공유 코드와 공유 UI를 보관하는 .NET Standard 라이브러리 프로젝트입니다.
  • Notes.Android - 이 프로젝트는 Android 관련 코드를 보관하며 Android 애플리케이션의 진입점입니다.
  • Notes.iOS - 이 프로젝트는 iOS 관련 코드를 보관하며 iOS 애플리케이션의 진입점입니다.

Xamarin.Forms 애플리케이션 분석

다음 스크린샷은 Mac용 Visual Studio의 Notes .NET Standard 라이브러리 프로젝트 콘텐츠를 보여줍니다.

Phoneword .NET Standard Library Project Contents

프로젝트에는 NuGetSDK 노드를 포함하는 종속성 노드가 있습니다.

  • NuGet - 프로젝트에 추가된 Xamarin.Forms, Xamarin.Essentials, Newtonsoft.Json 및 sqlite-net-pcl NuGet 패키지입니다.
  • SDK - .NET Standard를 정의하는 NuGet 패키지의 전체 집합을 참조하는 NETStandard.Library 메타패키지입니다.

프로젝트는 또한 다음과 같은 여러 파일로 구성됩니다.

  • Data\NoteDatabase.cs - 이 클래스에는 데이터베이스를 만들고, 데이터베이스에서 데이터를 읽고, 데이터베이스에 데이터를 쓰고, 데이터베이스에서 데이터를 삭제하는 코드가 포함되어 있습니다.
  • Models\Note.cs – 이 클래스는 인스턴스가 애플리케이션의 각 메모에 대한 데이터를 저장하는 Note 모델을 정의합니다.
  • Views\AboutPage.xaml - AboutPage 클래스의 XAML 태그로, 정보 페이지의 UI를 정의합니다.
  • Views\AboutPage.xaml.csAboutPage 클래스의 코드 숨김으로, 사용자가 페이지와 상호 작용할 때 실행되는 비즈니스 논리를 포함하고 있습니다.
  • Views\NotesPage.xaml - NotesPage 클래스의 XAML 태그로, 애플리케이션이 시작될 때 표시되는 페이지의 UI를 정의합니다.
  • Views\NotesPage.xaml.csNotesPage 클래스의 코드 숨김으로, 사용자가 페이지와 상호 작용할 때 실행되는 비즈니스 논리를 포함하고 있습니다.
  • Views\NoteEntryPage.xaml - NoteEntryPage 클래스의 XAML 태그로, 사용자가 노트를 입력할 때 표시되는 페이지의 UI를 정의합니다.
  • Views\NoteEntryPage.xaml.csNoteEntryPage 클래스의 코드 숨김으로, 사용자가 페이지와 상호 작용할 때 실행되는 비즈니스 논리를 포함하고 있습니다.
  • App.xaml - 애플리케이션의 리소스 사전을 정의하는 App 클래스에 대한 XAML 태그입니다.
  • App.xaml.csApp 클래스의 코드 숨김으로, Shell 애플리케이션 인스턴스화와 애플리케이션 수명 주기 이벤트 처리를 담당합니다.
  • AppShell.xaml – 애플리케이션의 시각적 계층 구조를 정의하는 AppShell 클래스의 XAML 태그입니다.
  • AppShell.xaml.csAppShell 클래스의 코드 숨김으로, 프로그래밍 방식으로 탐색할 수 있도록 NoteEntryPage에 대한 경로를 만듭니다.
  • AssemblyInfo.cs –이 파일은 어셈블리 수준에서 적용되는 프로젝트에 대한 애플리케이션 특성을 포함합니다.

Xamarin.iOS 애플리케이션에 대한 자세한 내용은 Xamarin.iOS 애플리케이션 분석을 참조하세요. Xamarin.Android 애플리케이션에 대한 자세한 내용은 Xamarin.Android 애플리케이션 분석을 참조하세요.

아키텍처 및 애플리케이션 기본 사항

Xamarin.Forms 애플리케이션은 전통적인 플랫폼 간 애플리케이션과 같은 방식으로 설계되었습니다. 공유 코드는 일반적으로 .NET 표준 라이브러리에 배치되고 플랫폼 관련 애플리케이션은 공유 코드를 사용합니다. 다음 다이어그램은 Notes 애플리케이션에 대한 해당 관계의 개요를 보여줍니다.

Notes Architecture

다음 코드 예제와 같이 시작 코드의 재사용을 최대화하기 위해 Xamarin.Forms 애플리케이션에는 각 플랫폼에서 애플리케이션 인스턴스화를 담당하는 App이라는 단일 클래스가 있습니다.

using Xamarin.Forms;

namespace Notes
{
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();
            MainPage = new AppShell();
        }
        // ...
    }
}

이 코드는 App 클래스의 MainPage 속성을 AppShell 개체로 설정합니다. AppShell 클래스는 애플리케이션의 시각적 계층 구조를 정의합니다. Shell은 이 시각적 계층 구조를 사용하고 해당 사용자 인터페이스를 생성합니다. 애플리케이션의 시각적 계층 구조를 정의하는 방법에 대한 자세한 내용은 애플리케이션 시각적 계층 구조를 참조하세요.

또한 AssemblyInfo.cs 파일에는 어셈블리 수준에서 적용되는 단일 애플리케이션 특성이 포함되어 있습니다.

using Xamarin.Forms.Xaml;

[assembly: XamlCompilation(XamlCompilationOptions.Compile)]

XamlCompilation 특성은 XAML이 중간 언어로 직접 컴파일되도록 XAML 컴파일러를 켭니다. 자세한 내용은 XAML 컴파일을 참조하세요.

각 플랫폼에서 애플리케이션 시작

각 플랫폼에서 애플리케이션을 시작하는 방법은 플랫폼에 따라 다릅니다.

iOS

iOS에서 초기 Xamarin.Forms 페이지를 시작하기 위해 Notes.iOS 프로젝트는 FormsApplicationDelegate 클래스에서 상속되는 AppDelegate 클래스를 정의합니다.

namespace Notes.iOS
{
    [Register("AppDelegate")]
    public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
    {
        public override bool FinishedLaunching(UIApplication app, NSDictionary options)
        {
            global::Xamarin.Forms.Forms.Init();
            LoadApplication(new App());
            return base.FinishedLaunching(app, options);
        }
    }
}

FinishedLaunching 재정의는 Init 메서드를 호출하여 Xamarin.Forms 프레임워크를 초기화합니다. 이렇게 하면 루트 뷰 컨트롤러가 LoadApplication 메서드에 대한 호출로 설정되기 전에 Xamarin.Forms의 iOS 특정 구현이 애플리케이션에 로드됩니다.

Android

Notes.Android 프로젝트는 Android에서 초기 Xamarin.Forms 페이지를 시작하기 위해 FormsAppCompatActivity 클래스에서 상속하는 작업을 사용하여 MainLauncher 특성을 가진 Activity를 만드는 코드를 포함하고 있습니다.

namespace Notes.Droid
{
    [Activity(Label = "Notes",
              Icon = "@mipmap/icon",
              Theme = "@style/MainTheme",
              MainLauncher = true,
              ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;

            base.OnCreate(savedInstanceState);
            global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
            LoadApplication(new App());
        }
    }
}

OnCreate 재정의는 Init 메서드를 호출하여 Xamarin.Forms 프레임워크를 초기화합니다. 이로 인해 Xamarin.Forms 애플리케이션이 로드되기 전에 Xamarin.Forms의 Android 특정 구현이 애플리케이션에 로드됩니다.

애플리케이션 시각적 계층 구조

Xamarin.Forms Shell 애플리케이션은 Shell 클래스를 서브클래싱하는 클래스에서 애플리케이션의 시각적 계층 구조를 정의합니다. Notes 애플리케이션에서는 Appshell 클래스입니다.

<Shell xmlns="http://xamarin.com/schemas/2014/forms"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       xmlns:views="clr-namespace:Notes.Views"
       x:Class="Notes.AppShell">
    <TabBar>
        <ShellContent Title="Notes"
                      Icon="icon_feed.png"
                      ContentTemplate="{DataTemplate views:NotesPage}" />
        <ShellContent Title="About"
                      Icon="icon_about.png"
                      ContentTemplate="{DataTemplate views:AboutPage}" />
    </TabBar>
</Shell>

이 XAML은 다음 두 가지 주요 개체로 구성됩니다.

  • TabBar. TabBar는 아래쪽 탭 표시줄을 나타내며, 애플리케이션의 탐색 패턴에서 아래쪽 탭이 사용될 때 사용해야 합니다. TabBar 개체는 Shell 개체의 자식입니다.
  • ShellContentTabBar에 있는 각 탭의 ContentPage 개체를 나타냅니다. 각 ShellContent 개체는 TabBar 개체의 자식입니다.

이러한 개체가 나타내는 것은 사용자 인터페이스가 아니라 애플리케이션의 시각적 계층 구조의 조직입니다. 셸은 이 개체를 사용하고 콘텐츠에 대한 탐색 사용자 인터페이스를 생성합니다. 따라서 AppShell 클래스는 하단 탭에서 탐색할 수 있는 두 페이지를 정의합니다. 페이지는 탐색에 대한 응답으로 요청에 따라 만들어집니다.

Shell 애플리케이션에 대한 자세한 내용은 Xamarin.Forms Shell을 참조하십시오.

사용자 인터페이스

Xamarin.Forms 애플리케이션의 사용자 인터페이스를 만드는 데 사용되는 여러 컨트롤 그룹이 있습니다.

  1. 페이지 – Xamarin.Forms 페이지는 플랫폼 간 모바일 애플리케이션 화면을 나타냅니다. Notes 애플리케이션은 ContentPage 클래스를 사용하여 단일 화면을 표시합니다. 페이지에 대한 자세한 내용은 Xamarin.Forms 페이지를 참조하세요.
  2. – Xamarin.Forms 뷰는 레이블, 단추 및 텍스트 입력 상자 등의 사용자 인터페이스에 표시되는 컨트롤입니다. 완성된 Notes 애플리케이션은 CollectionView, EditorButton 보기를 사용합니다. 뷰에 대한 자세한 내용은 Xamarin.Forms 뷰를 참조하세요.
  3. 레이아웃 – Xamarin.Forms 레이아웃은 뷰를 논리 구조로 구성하는 데 사용되는 컨테이너입니다. Notes 애플리케이션은 StackLayout 클래스를 사용하여 세로 스택에서 뷰를 정렬하고 Grid 클래스를 사용하여 단추를 가로로 정렬합니다. 레이아웃에 대한 자세한 내용은 Xamarin.Forms 레이아웃을 참조하세요.

런타임 시 각 컨트롤은 렌더링될 해당 고유 장치에 매핑됩니다.

Layout

Notes 애플리케이션은 StackLayout을 사용하여 화면 크기에 관계없이 화면에 자동으로 보기를 정렬하여 플랫폼 간 애플리케이션 개발을 단순화합니다. 각 자식 요소는 가로 또는 세로로 추가된 순서대로 차례로 위치가 지정됩니다. 얼마나 큰 공간을 StackLayout이 사용할지는 HorizontalOptionsVerticalOptions 속성을 어떻게 설정했는지에 달려 있지만, 기본적으로는 StackLayout은 전체 화면을 사용합니다.

다음 XAML 코드는 StackLayout을 사용하여 NoteEntryPage를 배열하는 예를 보여줍니다.

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Notes.Views.NoteEntryPage"
             Title="Note Entry">
    ...    
    <StackLayout Margin="{StaticResource PageMargin}">
        <Editor Placeholder="Enter your note"
                Text="{Binding Text}"
                HeightRequest="100" />
        <Grid>
            ...
        </Grid>
    </StackLayout>    
</ContentPage>

기본적으로 StackLayout은 세로 방향으로 가정합니다. 그러나 StackLayout.Orientation 속성을 StackOrientation.Horizontal 열거형 멤버로 설정하여 가로 방향으로 변경할 수 있습니다.

참고 항목

뷰의 크기는 HeightRequestWidthRequest 속성을 통해 설정할 수 있습니다.

StackLayout 클래스에 대한 자세한 내용은 Xamarin.Forms StackLayout을 참조하세요.

사용자 상호 작용에 응답

XAML에 정의된 개체는 코드 숨김 파일에서 처리되는 이벤트를 발생시킬 수 있습니다. 다음 코드 예제는 Save 단추에서 발생하는 Clicked 이벤트에 응답하여 실행되는 NoteEntryPage 클래스에 대한 코드 숨김의 OnSaveButtonClicked 메서드를 보여줍니다.

async void OnSaveButtonClicked(object sender, EventArgs e)
{
    var note = (Note)BindingContext;
    note.Date = DateTime.UtcNow;
    if (!string.IsNullOrWhiteSpace(note.Text))
    {
        await App.Database.SaveNoteAsync(note);
    }
    await Shell.Current.GoToAsync("..");
}

OnSaveButtonClicked 메서드는 데이터베이스에 메모를 저장하고 이전 페이지로 다시 이동합니다. 탐색에 대한 자세한 내용은 탐색을 참조하세요.

참고 항목

XAML 클래스의 코드 숨김 파일은 x:Name 특성으로 할당된 이름을 사용하여 XAML에서 정의된 개체에 접근할 수 있습니다. 이 특성에 할당된 값은 C# 변수와 동일한 규칙을 가지며, 따라서 문자 또는 밑줄로 시작해야 하고 공백을 포함하면 안 됩니다.

저장 단추를 OnSaveButtonClicked 메서드에 연결하는 동작은 NoteEntryPage 클래스에 대한 XAML 태그에서 발생합니다.

<Button Text="Save"
        Clicked="OnSaveButtonClicked" />

목록

CollectionView는 목록에 항목 컬렉션을 표시합니다. 기본적으로 목록 항목은 세로로 표시되고, 각 항목은 단일 행에 표시됩니다.

다음 코드 예제는 NotesPage에서 CollectionView를 보여줍니다.

<CollectionView x:Name="collectionView"
                Margin="{StaticResource PageMargin}"
                SelectionMode="Single"
                SelectionChanged="OnSelectionChanged">
    <CollectionView.ItemsLayout>
        <LinearItemsLayout Orientation="Vertical"
                           ItemSpacing="10" />
    </CollectionView.ItemsLayout>
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <StackLayout>
                <Label Text="{Binding Text}"
                       FontSize="Medium" />
                <Label Text="{Binding Date}"
                       TextColor="{StaticResource TertiaryColor}"
                       FontSize="Small" />
            </StackLayout>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

CollectionView에서 각 행의 레이아웃은 CollectionView.ItemTemplate 요소 내에 정의되며 데이터 바인딩을 사용하여 애플리케이션이 검색한 모든 메모를 표시합니다. CollectionView.ItemsSource 속성은 NotesPage.xaml.cs에서 데이터 원본으로 설정됩니다.

protected override async void OnAppearing()
{
    base.OnAppearing();

    collectionView.ItemsSource = await App.Database.GetNotesAsync();
}

이 코드는 CollectionView를 데이터베이스에 저장된 노트로 채우고, 페이지가 표시될 때 실행됩니다.

CollectionView에서 항목을 선택하면 SelectionChanged 이벤트가 발생합니다. 이벤트가 발생할 때 OnSelectionChanged라고 불리는 이벤트 처리기가 실행됩니다.

async void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (e.CurrentSelection != null)
    {
        // ...
    }
}

SelectionChanged 이벤트는 e.CurrentSelection 속성을 통해 항목과 연결된 개체에 액세스할 수 있습니다.

CollectionView 클래스에 대한 자세한 내용은 Xamarin.Forms CollectionView를 참조하세요.

이동할 URI를 지정하여 셸 애플리케이션에서 탐색을 수행합니다. 탐색 URI에는 다음 세 가지 구성 요소가 있습니다.

  • 경로 - 셸 시각적 계층 구조의 일부로 존재하는 콘텐츠의 경로를 정의합니다.
  • 페이지. 셸 시각적 계층 구조에 없는 페이지는 셸 애플리케이션 내의 어디에서나 탐색 스택으로 푸시할 수 있습니다. 예를 들어 NoteEntryPage 페이지는 Shell 시각적 계층 구조에서 정의되지 않지만 필요에 따라 탐색 스택으로 푸시할 수 있습니다.
  • 하나 이상의 쿼리 매개 변수. 쿼리 매개 변수는 탐색하는 동안 대상 페이지에 전달할 수 있는 매개 변수입니다.

탐색 URI는 세 가지 구성 요소를 모두 포함해야 하는 것은 아니지만 포함할 경우 구조는 다음과 같습니다. //route/page?queryParameters

참고 항목

경로는 Route 속성을 통해 Shell 시각적 계층 구조의 요소에서 정의될 수 있습니다. 하지만 Notes 애플리케이션에서와 같이 Route 속성이 설정되지 않은 경우 런타임에 경로가 생성됩니다.

Shell 탐색에 대한 자세한 내용은 Xamarin.Forms Shell 탐색을 참조하세요.

경로 등록

Shell 시각적 계층 구조에 없는 페이지로 이동하려면 먼저 Routing.RegisterRoute 메서드를 사용하여 Shell 라우팅 시스템에 해당 페이지를 등록해야 합니다. Notes 애플리케이션에서는 AppShell 생성자에서 수행됩니다.

public partial class AppShell : Shell
{
    public AppShell()
    {
        // ...
        Routing.RegisterRoute(nameof(NoteEntryPage), typeof(NoteEntryPage));
    }
}

이 예제에서는 NoteEntryPage라는 경로를 NoteEntryPage 형식에 대해 등록합니다. 그러면 애플리케이션 어디서나 URI 기반 탐색을 사용하여 이 페이지로 이동할 수 있습니다.

탐색 수행

탐색은 탐색할 경로를 나타내는 인수를 허용하는 GoToAsync 메서드를 통해 수행됩니다.

await Shell.Current.GoToAsync("NoteEntryPage");

이 예제에서는 NoteEntryPage를 탐색합니다.

Important

Shell 시각적 계층 구조에 없는 페이지로 이동하면 탐색 스택이 생성됩니다.

페이지로 이동하는 경우 데이터를 쿼리 매개 변수로 페이지에 전달할 수 있습니다.

async void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (e.CurrentSelection != null)
    {
        // Navigate to the NoteEntryPage, passing the ID as a query parameter.
        Note note = (Note)e.CurrentSelection.FirstOrDefault();
        await Shell.Current.GoToAsync($"{nameof(NoteEntryPage)}?{nameof(NoteEntryPage.ItemId)}={note.ID.ToString()}");
    }
}

이 예제는 CollectionView에서 현재 선택된 항목을 검색하고 NoteEntryPage.ItemId 속성에 쿼리 매개 변수로 전달되는 Note 개체의 ID 속성 값을 사용하여 NoteEntryPage로 이동합니다.

전달된 데이터를 수신하기 위해 NoteEntryPage 클래스는 QueryPropertyAttribute로 데코레이트됩니다.

[QueryProperty(nameof(ItemId), nameof(ItemId))]
public partial class NoteEntryPage : ContentPage
{
    public string ItemId
    {
        set
        {
            LoadNote(value);
        }
    }
    // ...
}

첫 번째 인수 QueryPropertyAttribute 는 속성이 ItemId 전달된 데이터를 받도록 지정하고 두 번째 인수는 쿼리 매개 변수 ID를 지정합니다. 따라서 QueryPropertyAttribute 위의 예제에서는 속성이 메서드 호출의 ItemId URI GoToAsync 에서 ItemId 쿼리 매개 변수에 전달된 데이터를 받도록 지정합니다. 그런 다음 ItemId 속성은 LoadNote 메서드를 호출하여 디바이스에서 노트를 검색합니다.

뒤로 탐색은 GoToAsync 메서드의 인수로 ".."를 지정하여 수행됩니다.

await Shell.Current.GoToAsync("..");

뒤로 탐색에 대한 자세한 내용은 뒤로 탐색을 참조하세요.

데이터 바인딩

데이터 바인딩은 Xamarin.Forms 애플리케이션이 데이터를 나타내고 해당 데이터와 상호 작용하는 방법을 단순화하기 위해 사용됩니다. 그것을 통해 사용자 인터페이스와 기본 애플리케이션 간에 연결이 설정됩니다. BindableObject 클래스에는 데이터 바인딩을 지원하는 인프라의 대부분이 담겨 있습니다.

데이터 바인딩은 소스대상이라는 두 개의 개체를 연결합니다. source 개체는 데이터를 제공합니다. target 개체는 원본 개체의 데이터를 사용(하고 종종 표시)합니다. 예를 들어 한 Editor(대상 개체)는 일반적으로 Text소스string 개체에 있는 해당 속성을 공용 속성에 바인딩합니다. 다음 다이어그램은 바인딩 관계를 보여 줍니다.

Data Binding

데이터 바인딩의 주요 장점은 더 이상 뷰와 데이터 원본 간의 데이터 동기화에 대해 걱정할 필요가 없다는 것입니다. source 개체의 변경 사항은 바인딩 프레임워크가 화면 뒤에서 target 개체에 자동으로 푸시하며, 대상(target) 개체의 변경 내용은 필요한 경우 source 개체로 다시 푸시될 수 있습니다.

데이터 바인딩 설정은 두 단계 프로세스입니다.

  • target 개체의 BindingContext 속성은 source에 설정되어야 합니다.
  • 바인딩이 sourcetarget 간에 설정되어야 합니다. XAML의 경우 Binding 태그 확장을 사용하여 이루어집니다.

Notes 애플리케이션에서 바인딩 대상은 메모를 표시하는 Editor이며, NoteEntryPageBindingContext로 설정된 Note 인스턴스는 바인딩 소스입니다. 처음에 NoteEntryPageBindingContext는 페이지 생성자가 실행될 때 설정됩니다.

public NoteEntryPage()
{
    // ...
    BindingContext = new Note();
}

이 예제에서는 NoteEntryPage가 만들어질 때 페이지의 BindingContext가 새로운 Note로 설정됩니다. 이는 애플리케이션에 새 노트를 추가하는 시나리오를 처리합니다.

또한 NotesPage에서 기존 노트를 선택했다면 NoteEntryPage로 이동이 이루어질 때에도 페이지의 BindingContext를 설정할 수 있습니다.

[QueryProperty(nameof(ItemId), nameof(ItemId))]
public partial class NoteEntryPage : ContentPage
{
    public string ItemId
    {
        set
        {
            LoadNote(value);
        }

        async void LoadNote(string itemId)
        {
            try
            {
                int id = Convert.ToInt32(itemId);
                // Retrieve the note and set it as the BindingContext of the page.
                Note note = await App.Database.GetNoteAsync(id);
                BindingContext = note;
            }
            catch (Exception)
            {
                Console.WriteLine("Failed to load note.");
            }
        }    
        // ...    
    }
}

이 예제에서 페이지 탐색이 발생하면 페이지의 BindingContext는 페이지를 데이터베이스에서 검색한 후 선택한 Note 개체로 설정됩니다.

Important

target 개체의 BindingContext 속성은 개별적으로 설정할 수 있으나, 그럴 필요는 없습니다. BindingContext는 자신의 모든 자식에서 상속한 특별 속성입니다. 따라서, ContentPageBindingContextNote 인스턴스에 설정될 경우, ContentPage의 모든 자식 항목은 동일한 BindingContext를 가지며 Note 개체의 공용 속성에 바인딩할 수 있습니다.

NoteEntryPageEditorNote 개체의 Text 속성에 바인딩합니다.

<Editor Placeholder="Enter your note"
        Text="{Binding Text}" />

source 개체의 Editor.Text 속성과 Text 속성 간의 바인딩이 설정됩니다. Editor에서 변경된 내용은 자동으로 Note 개체로 전파됩니다. 마찬가지로 Note.Text 속성을 변경하는 경우, Xamarin.Forms 바인딩 엔진은 Editor의 내용도 업데이트합니다. 이것을 양방향(two-way) 바인딩이라고 합니다.

데이터 바인딩에 대한 자세한 내용은 Xamarin.Forms 데이터 바인딩을 참조하세요.

스타일 적용

Xamarin.Forms 애플리케이션에는 동일한 모양의 여러 시각적 요소가 포함되어 있는 경우가 많습니다. 각 시각적 요소의 모양을 설정하는 것은 반복적인 작업이고 오류가 발생할 수 있습니다. 대신 모양을 정의한 다음 필요한 시각적 요소에 적용되는 스타일을 만들 수 있습니다.

Style 클래스는 속성 값 컬렉션을 하나의 개체로 그룹화한 다음 여러 시각적 요소 인스턴스에 적용할 수 있습니다. 스타일은 애플리케이션 수준, 페이지 수준 또는 보기 수준에서 ResourceDictionary에 저장됩니다. Style을 정의할 위치를 선택하면 사용할 수 있는 위치가 결정됩니다.

  • 애플리케이션 수준에서 정의한 Style 인스턴스는 애플리케이션 전체에 적용할 수 있습니다.
  • 페이지 수준에서 정의된 Style 인스턴스는 페이지 및 해당 자식에 적용될 수 있습니다.
  • 뷰 수준에서 정의된 Style 인스턴스는 뷰 및 해당 자식에 적용될 수 있습니다.

Important

애플리케이션에서 사용되는 모든 스타일은 중복을 피하기 위해 애플리케이션의 리소스 사전에 저장됩니다. 그러나 페이지에만 적용되는 XAML은 앱의 리소스 사전에 포함되어서는 안 됩니다. 그러면 애플리케이션 시작 시 페이지에서 요구할 경우 리소스가 대신 구문 분석되기 때문입니다. 자세한 내용은 애플리케이션 리소스 사전 크기 줄이기를 참조하세요.

Style 인스턴스에는 하나 이상의 Setter 개체의 컬렉션이 포함되며, 각 SetterPropertyValue를 가지고 있습니다. Property는 스타일이 적용된 요소의 바인딩 가능한 속성 이름이며 Value는 속성에 적용되는 값입니다. 다음 코드 예제에서는 NoteEntryPage의 스타일을 보여줍니다.

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Notes.Views.NoteEntryPage"
             Title="Note Entry">
    <ContentPage.Resources>
        <!-- Implicit styles -->
        <Style TargetType="{x:Type Editor}">
            <Setter Property="BackgroundColor"
                    Value="{StaticResource AppBackgroundColor}" />
        </Style>
        ...
    </ContentPage.Resources>
    ...
</ContentPage>

이 스타일은 페이지의 Editor 인스턴스에 적용됩니다.

Style을 만들 때 TargetType 속성이 항상 필요합니다.

참고 항목

Xamarin.Forms 애플리케이션 스타일 지정은 일반적으로 XAML 스타일을 사용하여 수행됩니다. 그러나 Xamarin.Forms는 CSS(CSS 스타일시트)를 사용하여 시각적 요소 스타일 지정도 지원합니다. 자세한 내용은 CSS(CSS 스타일시트)로 Xamarin.Forms 앱 스타일 지정을 참조하세요.

XAML 스타일에 대한 자세한 내용은 XAML 스타일을 사용하여 Xamarin.Forms 앱 스타일 지정을 참조하세요.

테스트 및 배포

Visual Studio와 Mac용 Visual Studio는 애플리케이션을 테스트하고 배포하기 위한 다양한 옵션을 제공합니다. 애플리케이션 디버그는 애플리케이션 개발 주기에서 일반적인 과정이며 코드 문제를 진단하는 데 도움이 됩니다. 자세한 내용은 중단점 설정, 단계별 코드 실행로그 창에 정보 출력을 참조하세요.

시뮬레이터는 애플리케이션 배포 및 테스트를 시작하기에 좋은 곳이며, 애플리케이션을 테스트하는 유용한 기능을 제공합니다. 그러나 사용자가 최종 애플리케이션을 시뮬레이터에서 사용하지는 않으므로, 초기에 자주 실제 디바이스에서 애플리케이션을 테스트해야 합니다. iOS 디바이스 프로비전에 대한 자세한 내용은 디바이스 프로비전을 참조하세요. Android 디바이스 프로비전에 대한 자세한 내용은 개발용 디바이스 설정을 참조하세요.

다음 단계

이 심층 분석에서는 Xamarin.Forms Shell을 사용한 애플리케이션 개발의 기본적인 사항을 살펴봤습니다. 제안된 다음 단계로는 다음 기능에 대한 내용이 있습니다.

  • Xamarin.Forms Shell은 대부분의 모바일 애플리케이션에 필요한 기본 기능을 제공하여 모바일 애플리케이션 개발의 복잡성을 줄입니다. 자세한 내용은 Xamarin.Forms Shell을 참조하세요.
  • Xamarin.Forms 애플리케이션의 사용자 인터페이스를 만드는 데 사용되는 여러 컨트롤 그룹이 있습니다. 자세한 내용은 컨트롤 참조를 참조하세요.
  • 데이터 바인딩은 두 개체의 속성을 연결하여 한 속성의 변경 내용이 다른 속성에 자동으로 반영되도록 하는 기술입니다. 자세한 내용은 데이터 바인딩을 참조하세요.
  • Xamarin.Forms는 사용되는 페이지 형식에 따라 여러 페이지 탐색 환경을 제공합니다. 자세한 내용은 탐색을 참조하세요.
  • 스타일을 통해 반복 태그를 줄이고, 애플리케이션 모양을 쉽게 변경할 수 있습니다. 자세한 내용은 Xamarin.Forms 앱 스타일 지정을 참조하세요.
  • 데이터 템플릿은 지원되는 보기에서 데이터 표현을 정의하는 기능을 제공합니다. 자세한 내용은 데이터 템플릿을 참조하세요.
  • 각 플랫폼의 네이티브 컨트롤을 사용자 지정할 수 있는 효과가 있습니다. 효과의 경우, 플랫폼별 프로젝트에서 PlatformEffect 클래스를 하위 클래스로 지정하여 만들어지고, 적절한 Xamarin.Forms 컨트롤에 연결하여 사용됩니다. 자세한 내용은 효과를 참조하세요.
  • 각 페이지, 레이아웃 및 보기는 차례로 네이티브 컨트롤을 만들고, 화면에 정렬하고, 공유 코드에 지정된 동작을 추가하는 Renderer 클래스를 사용하여 각 플랫폼에서 다르게 렌더링됩니다. 개발자는 컨트롤의 모양 및/또는 동작을 사용자 지정하기 위해 자신 만의 사용자 지정 Renderer 클래스를 구현할 수 있습니다. 자세한 내용은 사용자 지정 렌더러를 참조하세요.
  • 공유 코드는 DependencyService 클래스를 통해 네이티브 기능에 액세스할 수 있습니다. 자세한 내용은 DependencyService를 사용한 네이티브 기능 액세스를 참조하세요.

Channel 9YouTube에서 더 많은 Xamarin 비디오를 확인하세요.