XAML로 이벤트 처리

완료됨

XAML UI를 만든 후에는 사용자가 페이지를 방문할 때 발생하는 상호 작용에 응답하는 코드를 추가할 수 있습니다. .NET MAUI는 표준 .NET 이벤트를 통한 사용자 입력 및 상호 작용을 애플리케이션에게 알립니다.

이 단원에서는 이러한 이벤트를 처리하고 사용자가 기대하는 작업을 수행하는 방법을 알아봅니다.

XAML 페이지의 요소 이름 지정

이벤트 처리 코드는 페이지에서 특정 컨트롤 및 해당 속성을 참조해야 하는 경우가 많습니다. 각 컨트롤에 고유한 이름을 할당할 수 있습니다. 이렇게 하려면 XAML 특성 x:Name을 사용합니다. x:Name 특성은 다음과 같은 두 가지 작업을 수행합니다.

  • 생성되어 이 요소에 매핑되는 코드 숨김 파일에 비공개 필드가 추가됩니다. 코드에서 이 필드를 통해 시각적 요소와 상호 작용하여 런타임 속성을 설정하고 이벤트를 처리합니다.

  • 요소는 이 이름을 통해 XAML에 알려집니다. 동일한 XAML 파일에 정의된 다른 요소에서 이러한 요소를 참조할 수 있습니다.

요소 이름을 지정할 때 임의의 문자열을 사용할 수 없습니다. x:Name 특성에 할당된 값은 코드의 필드를 만드는 데 사용됩니다. 그 대신, 변수에 대한 명명 규칙을 준수해야 합니다. 또한 이름은 코드 숨김 정의로 컴파일되므로 고유해야 합니다.

요소의 이름을 입력한 후에는 코드 숨김 파일에서 해당 요소를 조작할 수 있습니다. 다음 XAML 조각은 Label 컨트롤을 정의합니다. 이름은 CounterLabel입니다(이 예는 .NET MAUI 템플릿이 생성하는 기본 앱에서 가져옴).

    <Label Text="Current count: 0"
        ...
        x:Name="CounterLabel"
        ... />

이 페이지의 코드 숨김에서는 CounterLabel 필드를 통해 이 컨트롤을 참조하고 해당 속성을 수정할 수 있습니다.

count++;
CounterLabel.Text = $"Current count: {count}";

Important

페이지의 InitializeComponent 메서드가 실행될 때까지 필드는 초기화되지 않습니다. 이 메서드는 XAML 구문 분석 및 개체 인스턴스화 프로세스의 일부입니다. 이 호출 후 XAML로 정의된 요소와 상호 작용하는 코드를 배치합니다. 이 규칙의 예외는 ContentPage 클래스 자체입니다. InitializeComponent 메서드를 실행하기 전에 클래스의 모든 속성에 액세스할 수 있습니다. 그러나 이 클래스의 속성을 XAML로 설정하면 이러한 속성 값은 InitializeComponent를 실행하기 전에 설정된 모든 값을 덮어씁니다.

특성을 사용하여 이벤트 연결

대부분의 컨트롤은 단추에 대한 Clicked 이벤트처럼, 해당 컨트롤이 응답할 수 있는 이벤트에 해당하는 속성을 노출합니다. 다양한 컨트롤이 다양한 이벤트 집합을 지원합니다. 예를 들어 Button 컨트롤은 Clicked, PressedReleased 이벤트에 응답할 수 있고 Entry 컨트롤은 TextChanged 등의 이벤트를 갖습니다. 페이지의 XAML 태그에서 이벤트 속성을 초기화하고 이벤트가 트리거될 때 실행할 메서드의 이름을 지정할 수 있습니다. 이벤트 메서드는 다음 서명 요구 사항을 충족해야 합니다.

  • 값을 반환할 수 없습니다. 메서드는 void이어야 합니다.
  • 두 개의 매개 변수를 사용해야 합니다. 즉, 이벤트를 트리거한 개체(보낸 사람이라고 함)를 표시하는 object 참조와 보낸 사람에서 이벤트 처리기에 전달된 인수를 포함하는 EventArgs 매개 변수입니다.
  • 이벤트 처리기는 private이어야 합니다. 이는 강제되지 않지만 이벤트 처리기를 공용으로 설정하면 외부 세계에서 액세스할 수 있게 되며 트리거되는 예상 이벤트 이외의 작업이 이를 호출할 수 있습니다.
  • 이벤트 처리기는 비동기 작업을 실행해야 하는 경우 async일 수 있습니다.

다음 예에서는 .NET MAUI 템플릿의 샘플 앱에 있는 단추에 대한 Clicked 이벤트 처리기의 정의를 보여 줍니다. 메서드 이름은 표준 규칙을 따릅니다. 즉, 컨트롤 이름(단추 이름: Counter), 이벤트 이름(Clicked) 다음에 On이 옵니다. 이 규칙은 강제는 아니지만 지키는 것이 좋습니다.

private void OnCounterClicked(object sender, EventArgs e)
{
    ...
}

문제의 분리

XAML에서 이벤트를 연결하는 것은 편리하지만 컨트롤 동작과 UI 정의가 혼합됩니다. 대부분의 개발자는 이러한 요소를 분리하고 코드 숨김의 모든 이벤트 처리기에서 명명된 요소를 구독하는 것을 선호합니다. 연결된 내용과 동작이 매핑된 위치를 확인하는 것이 더 쉽습니다. 또한 이 메서드는 실수로 자신도 모르게 XAML로 처리기를 제거하여 코드를 손상시킬 가능성이 별로 없습니다. 컴파일러는 제거된 처리기를 catch하지 않으며 코드가 해당 동작을 제대로 수행하지 않는 경우에만 문제로 표시됩니다.

이벤트 처리기를 XAML을 사용하여 연결할지 또는 코드를 사용하여 연결할지는 개인적인 선택 사항입니다.

코드에서 이벤트 처리기를 연결하려면 += 연산자를 사용하여 이벤트를 구독합니다. 일반적으로 InitializeComponent 호출 후 페이지의 생성자에서 이 작업을 수행합니다.

public partial class MainPage : ContentPage, IPage
{
    public MainPage()
    {
        InitializeComponent();
        Counter.Clicked += OnCounterClicked;
    }

    ...

    private void OnCounterClicked(object sender, EventArgs e)
    {
        ...
    }
}

참고

이 방법을 사용하여 동일한 이벤트에 대해 여러 이벤트 처리 메서드를 구독할 수 있습니다. 각 이벤트 처리 메서드는 이벤트가 발생할 때 실행되지만 특정 순서로 실행될 것이라고 가정해서는 안 되므로 메서드 간에 종속성을 도입하지 마세요.

마찬가지로 애플리케이션의 뒷부분에서 -= 연산자를 사용하여 이벤트에서 구독을 취소하여 이벤트 처리기를 제거할 수 있습니다.

Counter.Clicked -= OnCounterClicked;

지식 점검

1.

이벤트 처리 메서드에 전달되는 매개 변수는 무엇인가요?

2.

C#의 이벤트에 이벤트 처리기를 연결하는 데 사용할 수 있는 연산자는 무엇인가요?