WPF 개발, INotifyPropertyChanged

Windows Presentation Foundation (WPF)은 .NET Framework의 일부로, 데스크톱 애플리케이션을 위한 강력한 UI 프레임워크입니다. WPF의 가장 큰 장점 중 하나는 MVVM (Model-View-ViewModel) 패턴을 지원하여, 사용자 인터페이스와 비즈니스 로직을 분리할 수 있다는 점입니다. 그러나, 이러한 구조에서 데이터 바인딩이 올바르게 작동하려면 INotifyPropertyChanged 인터페이스를 이해하고 구현하는 것이 필수적입니다.

INotifyPropertyChanged란?

INotifyPropertyChanged는 .NET Framework의 System.ComponentModel 네임스페이스에 정의된 인터페이스입니다. 이 인터페이스는 데이터의 변경 사항을 UI에 자동으로 알리기 위해 사용됩니다. 데이터 바인딩을 통해 UI 요소와 데이터 소스 간의 동기화를 가능하게 합니다.

WPF에서 데이터 바인딩은 중요하며, 모델(M)과 뷰(V) 간의 구성을 관리하는 데 중요한 역할을 합니다. INotifyPropertyChanged 인터페이스를 구현한 클래스는 프로퍼티 값이 변경될 때 UI에 변경 사항을 알릴 수 있습니다. 이를 통해 UI는 최신 정보를 항상 표시합니다.

INotifyPropertyChanged 인터페이스의 구성

INotifyPropertyChanged 인터페이스는 아래와 같은 구성 요소로 이루어져 있습니다.

  • PropertyChanged 이벤트: 이 이벤트는 프로퍼티의 값이 변경될 때 발생하며, UI는 이 이벤트를 구독하여 데이터 변경을 감지할 수 있습니다.
  • OnPropertyChanged 메서드: 이 메서드는 특정 프로퍼티의 값이 변경되었음을 알리기 위해 PropertyChanged 이벤트를 발생시키는 역할을 합니다.

아래는 INotifyPropertyChanged 인터페이스의 정의입니다:

public interface INotifyPropertyChanged
{
    event PropertyChangedEventHandler PropertyChanged;
}

INotifyPropertyChanged 구현하기

다음은 INotifyPropertyChanged를 구현하는 방법에 대한 예제입니다. ‘Person’이라는 간단한 모델 클래스를 정의해보겠습니다.

using System;
using System.ComponentModel;

public class Person : INotifyPropertyChanged
{
    private string name;
    private int age;

    public string Name
    {
        get { return name; }
        set
        {
            if (name != value)
            {
                name = value;
                OnPropertyChanged("Name");
            }
        }
    }

    public int Age
    {
        get { return age; }
        set
        {
            if (age != value)
            {
                age = value;
                OnPropertyChanged("Age");
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

코드 설명

  • 필드: nameage라는 두 개의 private 필드를 정의했습니다.
  • 속성: NameAge라는 public 속성을 정의합니다. 속성의 set 접근자에서 값이 변경될 경우 OnPropertyChanged 메서드를 호출하여 UI에 변경 사항을 알립니다.
  • 이벤트: PropertyChanged 이벤트를 선언하고, OnPropertyChanged 메서드를 통해 이를 발생시킵니다.

WPF에서 INotifyPropertyChanged 사용하기

이제 WPF 애플리케이션에서 INotifyPropertyChanged를 사용하는 방법을 살펴보겠습니다. 간단한 WPF 애플리케이션을 생성하고, 사용자 인터페이스를 통해 Person 모델을 바인딩해 보겠습니다.

XAML 코드

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="200" Width="400">
    <Grid>
        <StackPanel>
            <TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}" />
            <TextBox Text="{Binding Age, UpdateSourceTrigger=PropertyChanged}" />
            <TextBlock Text="이름: {Binding Name}" FontWeight="Bold" />
            <TextBlock Text="나이: {Binding Age}" FontWeight="Bold" />
        </StackPanel>
    </Grid>
</Window>

코드 비하인드

using System.Windows;

public partial class MainWindow : Window
{
    public Person Person { get; set; }

    public MainWindow()
    {
        InitializeComponent();
        Person = new Person() { Name = "홍길동", Age = 30 };
        DataContext = Person;
    }
}

코드 설명

  • DataContext 설정: 생성자에서 Person 인스턴스를 생성하고 DataContext를 설정해 UI와 모델을 연결합니다.
  • XAML 바인딩: TextBoxTextBlock에서 Person 모델의 속성과 바인딩이 이루어집니다. 이 때 UpdateSourceTrigger=PropertyChanged를 사용하여 사용자가 입력할 때마다 변경 사항을 즉시 전송합니다.

프로퍼티 변경 통지의 중요성

WPF에서 INotifyPropertyChanged를 사용하는 주된 이유는 UI가 데이터의 변화를 감지하고 사용자에게 최신 정보를 표시하도록 하기 위해 아닙니다. 다음은 이러한 변경 통지의 중요성을 강조하는 몇 가지 포인트입니다.

  • UI와 데이터의 동기화: 사용자가 데이터를 입력하면 UI가 즉시 반영됩니다. 이는 사용자 경험을 향상시킵니다.
  • 모델과 뷰 간의 분리: MVVM 패턴을 통해 각 구성 요소가 독립적으로 작동하도록 할 수 있습니다.
  • 테스트 가능성: 비즈니스 로직이 UI와 분리되어 있어 단위 테스트가 용이합니다.

다양한 시나리오에서의 INotifyPropertyChanged 활용

WPF의 INotifyPropertyChanged는 다양한 시나리오에서 활용될 수 있습니다. 몇 가지 예시를 통해 이 인터페이스의 유용성을 설명하겠습니다.

컬렉션 변경 통지

INotifyPropertyChanged는 프로퍼티의 변경 통지만 담당하지만, 컬렉션이 변경되는 경우에는 INotifyCollectionChanged를 사용할 수 있습니다. 그러나, 컬렉션 안의 요소가 변경될 경우에는 각 요소가 INotifyPropertyChanged를 구현해야 합니다.

뷰모델에서의 활용

MVVM 패턴에서 뷰모델은 UI와 모델 간의 중재자 역할을 합니다. 뷰모델에서 INotifyPropertyChanged를 구현하여 UI에서의 사용자 입력에 대한 실시간 반응을 제공합니다. 예를 들어, 로그인 상태를 나타내는 IsLoggedIn 속성을 추가할 수 있습니다.

public class UserViewModel : INotifyPropertyChanged
{
    private bool isLoggedIn;
    
    public bool IsLoggedIn
    {
        get { return isLoggedIn; }
        set
        {
            if (isLoggedIn != value)
            {
                isLoggedIn = value;
                OnPropertyChanged("IsLoggedIn");
            }
        }
    }

    // INotifyPropertyChanged 구현 생략...
}

결론

WPF에서 INotifyPropertyChanged는 데이터 바인딩의 필수적인 요소입니다. 데이터를 변경하고 그 변경을 UI에 반영하는 데 있어 이 인터페이스의 역할은 매우 중요합니다. INotifyPropertyChanged를 사용하는 방법을 숙지하고, MVVM 패턴을 통해 뷰와 모델 간의 분리를 통해 코드를 더욱 깔끔하고 유지 보수하기 쉬운 형태로 발전시킬 수 있습니다. 이 강좌를 통해 INotifyPropertyChanged 인터페이스에 대한 이해를 높이고, WPF 애플리케이션에서 더욱 효과적으로 활용할 수 있기를 바랍니다.