.NET MAUI 앱에 시각적 개체 컨트롤 추가

완료됨

이제 .NET MAUI 템플릿을 사용하여 애플리케이션을 만들었으므로 다음 단계는 사용자 인터페이스를 추가하고 초기 UI 논리를 구현하는 것입니다.

이 단원에서는 .NET MAUI(다중 플랫폼 애플리케이션 사용자 인터페이스) 애플리케이션의 구성 요소와 탐색 구조에 대해 자세히 알아봅니다.

.NET MAUI 프로젝트에는 무엇이 있나요?

요약하자면, .NET MAUI 프로젝트에는 처음에 다음이 포함됩니다.

  • Application 개체를 만들고 구성하는 코드가 포함된 MauiProgram.cs 파일

  • UI 리소스를 제공하고 애플리케이션의 초기 창을 만드는 App.xamlApp.xaml.cs 파일.

  • 애플리케이션의 초기 페이지를 지정하고 탐색 라우팅을 위한 페이지 등록을 처리하는 AppShell.xamlAppShell.xaml.cs 파일.

  • 초기 창에 기본적으로 표시되는 페이지의 레이아웃 및 UI 논리를 정의하는 MainPage.xamlMainPage.xaml.cs 파일.

앱에 페이지를 필요한 만큼 더 추가할 수 있으며, 앱에 필요한 비즈니스 논리를 구현하는 추가 클래스를 만들 수 있습니다.

.NET MAUI 프로젝트에는 이미지, 아이콘 및 글꼴과 같은 기본 애플리케이션 리소스 세트와 각 플랫폼의 기본 부트스트랩 코드도 포함됩니다.

애플리케이션 클래스

App 클래스는 .NET MAUI 애플리케이션 전체를 나타냅니다. 이 클래스는 Microsoft.Maui.Controls.Application에서 기본 동작 세트를 상속합니다. 이전 단원에서 각 플랫폼의 부트스트랩 코드를 통해 인스턴스화되고 로드된 App 클래스입니다. App 클래스 생성자는 일반적으로 AppShell 클래스의 인스턴스를 만들어서 MainPage 속성에 할당합니다. 이 코드는 AppShell의 정의에 따라 사용자에게 보이는 첫 번째 화면을 제어합니다.

App 클래스에는 다음 항목도 있습니다.

  • 앱을 백그라운드로 보내는 경우(즉 포그라운드 앱이 중지되는 경우)를 포함하여 수명 주기 이벤트를 처리하는 메서드

  • 애플리케이션에 대한 새 Windows를 만드는 메서드. 기본적으로 .NET MAUI 애플리케이션에는 창이 하나 있지만 창을 추가로 만들고 시작할 수 있습니다. 이렇게 하면 데스크톱 및 태블릿 애플리케이션에서 더 좋습니다.

.NET MAUI(.NET Multi-platform App UI) Shell은 다음을 포함하여 대부분의 앱에 필요한 기본 기능을 제공하여 앱 개발의 복잡성을 줄입니다.

  • 앱의 시각적 계층 구조를 설명하는 단일 위치
  • 일반적인 탐색 사용자 환경입니다.
  • 앱의 모든 페이지를 탐색할 수 있도록 허용하는 URI 기반 탐색 체계
  • 통합된 검색 처리기입니다.

.NET MAUI Shell 앱에서 앱의 시각적 계층 구조는 Shell 클래스의 서브클래스인 클래스에 설명되어 있습니다. 이 클래스는 다음 세 가지 주요 계층적 개체로 구성될 수 있습니다.

  • FlyoutItem 또는 TabBar. FlyoutItem은(는) 플라이아웃에서 하나 이상의 항목을 나타내며, 앱의 탐색 패턴에 플라이아웃이 필요할 때 사용해야 합니다. TabBar은(는) 하단 탭 표시줄을 표시하며, 앱의 탐색 패턴이 아래쪽 탭으로 시작되고 플라이아웃이 필요하지 않을 때 사용해야 합니다.
  • Tab. 아래쪽 탭으로 탐색할 수 있는 그룹화된 콘텐츠를 나타냅니다.
  • 각 탭의 ContentPage 개체를 나타내는 ShellContent.

이러한 개체는 사용자 인터페이스를 나타내는 것이 아니라 앱의 시각적 계층 구조를 구성합니다. Shell은 이러한 개체를 사용하고 콘텐츠에 대한 탐색 사용자 인터페이스를 생성합니다.

페이지

페이지는 Shell 내부에 있는 .NET MAUI의 UI 계층 구조 루트입니다. 지금까지 본 솔루션에는 MainPage라는 클래스가 포함되어 있습니다. 이 클래스는 가장 간단하고 일반적인 페이지 형식인 ContentPage에서 파생됩니다. 콘텐츠 페이지는 해당 콘텐츠만 표시합니다. .NET MAUI에는 다음을 포함하여 여러 가지 다른 기본 제공 페이지 형식도 있습니다.

  • TabbedPage: 탭 탐색에 사용되는 루트 페이지입니다. 탭 페이지에는 각 탭마다 하나씩 자식 페이지 개체가 포함됩니다.

  • FlyoutPage: 마스터/세부 정보 스타일 프레젠테이션을 구현할 수 있습니다. 플라이아웃 페이지에는 항목 목록이 포함되어 있습니다. 항목을 선택하면 해당 항목의 세부 정보를 보여주는 보기가 나타납니다.

다른 페이지 형식도 사용할 수 있으며, 대부분은 다중 화면 앱에서 여러 탐색 패턴을 사용하도록 설정하는 데 사용됩니다.

콘텐츠 페이지에는 일반적으로 보기가 표시됩니다. 보기에서는 특정 방법으로 데이터를 검색하고 표시할 수 있습니다. 콘텐츠 페이지의 기본 보기는 항목을 있는 그대로 표시하는 ContentView입니다. 보기를 축소하면 보기 크기를 조정할 때까지 항목이 디스플레이에서 사라질 수 있습니다. ScrollView을(를) 사용하면 스크롤 창에 항목을 표시할 수 있습니다. 창을 축소하면 위아래로 스크롤하여 항목을 표시할 수 있습니다. CarouselView는 사용자가 항목 컬렉션을 살짝 밀 수 있는 스크롤 가능한 보기입니다. CollectionView는 템플릿을 사용하여 명명된 데이터 원본에서 데이터를 검색하고 각 항목을 형식으로 표시할 수 있습니다. 그 외에도 여러 가지 유형의 보기를 사용할 수 있습니다.

컨트롤 및 레이아웃

보기에는 단추, 레이블 또는 텍스트 상자와 같은 단일 컨트롤이 포함될 수 있습니다. (엄밀히 말해서 보기 자체는 컨트롤이므로 보기에 다른 보기가 포함될 수 있습니다.) 그러나 단일 컨트롤로 제한된 사용자 인터페이스는 별로 유용하지 않으므로 컨트롤이 레이아웃에 배치됩니다. 레이아웃은 컨트롤이 서로에게 상대 위치로 표시되는 규칙을 정의합니다. 레이아웃도 컨트롤이므로 보기에 추가할 수 있습니다. 기본 MainPage.xaml 파일을 보면 이 페이지/보기/레이아웃/컨트롤 계층 구조가 작동하는 것을 볼 수 있습니다. 이 XAML 코드에서 VerticalStackLayout 요소는 다른 컨트롤의 레이아웃을 미세 조정할 수 있는 또 다른 컨트롤입니다.

<ContentPage ...>
    <ScrollView ...>
        <VerticalStackLayout>
            <Image ... />
            <Label ... />
            <Label ... />
            <Button ... />
        </VerticalStackLayout>
    </ScrollView>
</ContentPage>

다음은 레이아웃을 정의하는 데 사용되는 일반 컨트롤입니다.

  • 위에서 아래로 또는 왼쪽에서 오른쪽으로 스택에 컨트롤을 배치하도록 최적화된 스택 레이아웃인 VerticalStackLayoutHorizontalStackLayout. StackLayout을(를) 사용할 수도 있습니다. 이 레이아웃에는 Horizontal 또는 Vertical(으)로 설정할 수 있는 StackOrientation 속성이 있습니다. 태블릿 또는 휴대폰에서 애플리케이션 코드의 이 속성을 수정하면 다음과 같이 사용자가 디바이스를 회전할 때 디스플레이를 조정할 수 있습니다.

    스택 레이아웃의 수평 및 수직 방향이 어떻게 컨트롤을 배치하는지에 대한 다이어그램.

  • AbsoluteLayout - 컨트롤의 정확한 좌표를 설정할 수 있습니다.

  • FlexLayout - 단일 행 또는 열에 맞지 않는 경우 포함된 자식 컨트롤을 래핑할 수 있다는 점을 제외하면 StackLayout과 비슷합니다. 이 레이아웃은 맞춤 및 다양한 화면 크기에 맞게 조정하는 옵션도 제공합니다. 예를 들어, FlexLayout 컨트롤은 수직으로 배열할 때 자식 컨트롤을 왼쪽, 오른쪽 또는 가운데에 맞출 수 있습니다. 가로로 정렬하면 컨트롤의 간격을 균일하게 맞추기 위해 맞춤 설정할 수 있습니다. ScrollView 내부에 가로 FlexLayout을 사용하여 가로로 스크롤 가능한 일련의 프레임을 표시할 수 있습니다(각 프레임 자체는 세로로 정렬되는 FlexLayout 가능).

    FlexLayout이 화면에 렌더링된 상태로 실행되는 앱의 스크린샷. 먼저 이미지가 렌더링되고, 그다음에 제목이 렌더링되고, 그다음에 텍스트 레이블이 렌더링되고 마지막으로 단추가 렌더링됩니다. 이러한 모든 요소는 상자 안에 수직으로 렌더링됩니다.

  • Grid - 사용자가 설정한 열과 행 위치에 따라 컨트롤을 배치합니다. 열과 행의 크기 및 범위를 정의할 수 있으므로 그리드 레이아웃이 반드시 "바둑판 모양"이 되지 않습니다.

다음 이미지는 이러한 일반적인 레이아웃 유형의 주요 특성을 요약한 것입니다.

.NET MAUI UI에서 가장 자주 사용되는 레이아웃의 다이어그램.

스택 레이아웃에는 세로로 정렬된 4개의 상자가 표시됩니다. 절대 레이아웃은 개발자가 지정한 위치에 정확히 화면에 정렬된 4개의 상자를 표시합니다. 플렉스 레이아웃은 화면 영역을 최대한 활용하기 위해 화면에 배치된 여러 상자를 보여 줍니다. 그리드 레이아웃은 화면에 그리드 패턴으로 배치된 여러 상자를 표시합니다.

모든 컨트롤에는 속성이 있습니다. XAML(Extensible Application Markup Language)을 사용하여 이러한 속성에 대한 초기 값을 설정할 수 있습니다. 대부분의 경우 애플리케이션의 C# 코드에서 이러한 속성을 수정할 수 있습니다. 예를 들어 기본 .NET MAUI 앱의 Click me 단추에 대한 Clicked 이벤트를 처리하는 코드는 다음과 같습니다.

int count = 0;
private void OnCounterClicked(object sender, EventArgs e)
{
    count+=5;

    if (count == 1)
        CounterBtn.Text = $"Clicked {count} time";
    else
        CounterBtn.Text = $"Clicked {count} times";

    SemanticScreenReader.Announce(CounterBtn.Text);
}

이 코드는 페이지에서 CounterBtn 컨트롤의 Text 속성을 수정합니다. 코드에서 전체 페이지, 보기 및 레이아웃을 만들 수도 있습니다. XAML을 사용할 필요가 없습니다. 예를 들어 페이지의 다음 XAML 정의를 생각해 보세요.

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Phoneword.MainPage">

    <ScrollView>
        <VerticalStackLayout>
            <Label Text="Current count: 0"
                Grid.Row="0"
                FontSize="18"
                FontAttributes="Bold"
                x:Name="CounterLabel"
                HorizontalOptions="Center" />

            <Button Text="Click me"
                Grid.Row="1"
                Clicked="OnCounterClicked"
                HorizontalOptions="Center" />
        </VerticalStackLayout>
    </ScrollView>
</ContentPage>

C#의 동일한 코드는 다음과 같습니다.

public partial class TestPage : ContentPage
{
    int count = 0;
    
    // Named Label - declared as a member of the class
    Label counterLabel;

    public TestPage()
    {       
        var myScrollView = new ScrollView();

        var myStackLayout = new VerticalStackLayout();
        myScrollView.Content = myStackLayout;

        counterLabel = new Label
        {
            Text = "Current count: 0",
            FontSize = 18,
            FontAttributes = FontAttributes.Bold,
            HorizontalOptions = LayoutOptions.Center
        };
        myStackLayout.Children.Add(counterLabel);
        
        var myButton = new Button
        {
            Text = "Click me",
            HorizontalOptions = LayoutOptions.Center
        };
        myStackLayout.Children.Add(myButton);

        myButton.Clicked += OnCounterClicked;

        this.Content = myScrollView;
    }

    private void OnCounterClicked(object sender, EventArgs e)
    {
        count++;
        counterLabel.Text = $"Current count: {count}";

        SemanticScreenReader.Announce(counterLabel.Text);
    }
}

C# 코드는 더 자세하지만, UI를 동적으로 조정할 수 있는 더 많은 유연성을 제공합니다.

애플리케이션이 실행되기 시작할 때 이 페이지를 표시하려면 AppShellTestPage 클래스를 기본 ShellContent로 설정합니다.

<ShellContent
        Title="Home"
        ContentTemplate="{DataTemplate local:TestPage}"
        Route="TestPage" />

레이아웃 튜닝

컨트롤 주위에 빈 공간을 약간 추가하는 것이 좋습니다. 각 컨트롤에는 레이아웃이 준수하는 Margin 속성이 있습니다. 여백은 다른 것을 밀어내는 컨트롤로 간주할 수 있습니다.

모든 레이아웃에는 자식 항목이 레이아웃의 테두리 가까이에 접근하지 못하도록 하는 Padding 속성도 있습니다. 이 개념에 대해 고려할 수 있는 한 가지 방법은 모든 컨트롤이 하나의 상자 안에 있고, 이 상자에는 패딩된 벽이 있다는 것입니다.

또 다른 유용한 공백 설정은 VerticalStackLayout 또는 HorizontalStackLayoutSpacing 속성입니다. 이는 레이아웃의 모든 자식 간의 공간을 설정합니다. 값은 컨트롤 자체의 여백에 더해지므로 실제 공백은 여백에 간격을 더한 값입니다.

지식 점검

1.

다음 중 .NET MAUI의 레이아웃 형식이 아닌 것은 무엇인가요?

2.

.NET MAUI에서 화면을 만드는 데 사용되는 클래스는 무엇인가요?

정답 확인