[c#] 클래스 리스트를 쉽게 DataGridView에 바인드하기 – ObservableObject

클래스 리스트를 DataGridView에 연결하여 리스트 아이템의 필드가 바뀐 때 후자에 반영되게 하려면 INotifyPropertyChanged.PropertyChanged 이벤트를 써야 한다. 이거는 원칙적으로 클래스의 각 필드에 구현을 해야 한다. 많이 번거롭고 코드도 길어진다.

더 편하게 하려면 클래스 리스트를 쓰지 않고 아예 DataTable을 이용한다. 하지만 이건 클래스 리스트보다 느리다.

변칙적인 방법인데 ObservableObject를 이용하면 클래스 리스트를 이용해서도 쉽게 구현할 수 있다. 이걸 이용하면 컴파일을 할 때 자동으로 코드가 만들어진다.

using CommunityToolkit.Mvvm.ComponentModel;

public partial class TestClass : ObservableObject
{
    [ObservableProperty] private int _int;
}

BindingList<TestClass> TestClasses = new();

private void Form1_Load(object sender, EventArgs e)
{
    dataGridView1.DataSource = TestClasses;

    TestClass testClass = new();

    testClass.Int = 0;

    TestClasses.Add(testClass);
}

private void Form1_Click(object sender, EventArgs e)
{
    TestClasses[0].Int = 1;
}

우선 이 클래스를 이용하려면 누게트로 CommunityToolkit.Mvvm를 설치해야 한다. 마이크로소프트가 만든 거다. 주의해야 하는 부분들을 굵은 글꼴로 출력했다.

클래스에 partial 키워드를 써야 한다.

Partial type definitions allow for the definition of a class, struct, interface, or record to be split into multiple definitions.
Partial type (C# Reference)

partial 클래스를 만들면 다른 데서도 이 클래스를 정의할 수 있다. ObservableObject를 이용하면 자동으로 코드가 만들어지므로 프로그래머가 정의한 클래스를 다른 데서 수정하게 된다.

필드는 private로 선언한다. 이 필드는 프로그래머가 호출할 게 아니라 ObservableObject가 자동으로 코드를 만드는 데에 쓰인다. private를 생략해도 private로 선언된다.

프라퍼티로 선언하지 않는다. 따라서 { get; set; }은 필요하지 않다.

필드의 이름은 소문자나 _로 시작해야 한다. ObservableObject는 이걸 대문자로 바꾸며 _는 없앤다.

필드를 호출할 땐 대문자로 바뀐 게 보일 거다. 편집기는 이걸 오류로 인식하지만 컴파일은 정상으로 되고 일단 컴파일을 한 뒤에는 오류로 표시하지 않는다.

열의 이름을 설정하려면 아래와 같이 한다.

[ObservableProperty][property: DisplayName("정수")] private int _int;