c# INotifyPropertyChanged를 이용하여 BindingList를 DataGridView에 연결하기
DataGridView에 연결하는 컬렉션으로 크게 List, BindingList, DataTable 세 가지를 이용한다.
List에는 아이템을 추가하거나 삭제한 때 DataGridView에 반영되지 않는 문제가 있다. DataTable는 느려서 이용하기 곤란할 때가 있다. BindingList에는 아이템을 수정한 때 DataGridView에 반영되지 않는 단점이 있다.
windows forms 애플리캐이션에서 BindingList를 DataGridView에 연결하고 전자의 아이템 값이 바뀐 때 이 값을 DataGridView에 반영하려면 INotifyPropertyChanged 인터패이스를 쓰는 게 제일 좋다.
class Class1 : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
void NotifyPropertyChanged([CallerMemberName] string propertyName = default)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
int Int_ { get; set; }
string String_ { get; set; }
public int Int
{
get => Int_;
set { if (Int_ != value) { Int_ = value; NotifyPropertyChanged(); } }
}
public string String
{
get => String_;
set { if (String_ != value) { String_ = value; NotifyPropertyChanged(); } }
}
}
BindingList의 아이템 값이 바뀐 때 이를 DataGridView에 반영하는 건 이벤트다. 따라서 INotifyPropertyChanged의 이벤트인 PropertyChangedEventHandler를 선언해야 한다. 인텔리센스를 이용하면 자동으로 만들 수 있다.
To implement interface events in a class
Declare the event in your class and then invoke it in the appropriate areas.
How to implement interface events (C# Programming Guide)
PropertyChanged는 널일 수 있으므로 PropertyChangedEventHandler를 널러블인 PropertyChangedEventHandler?로 선언한다. 클래스를 아무 것에도 바인드하지 않고 프라퍼티를 수정하면 PropertyChanged가 널이 된다. 널러블로 선언하지 않고 바인드도 하지 않고 프라퍼티를 수정하면 예외로 처리된다.
메떠드의 패러미터에 CallerMemberName 애트리뷰트를 설정하면 설정된 문자열 변수에 이 메떠드를 호출한 caller의 이름이 들어간다.
Allows you to obtain the method or property name of the caller to the method.
CallerMemberNameAttribute Class
호출자의 이름을 얻으려면 문자열 변수에 아무 값이라도 넣어 놔야 한다. 그냥 string propertyName이라고 선언하면 안 된다.
You apply the CallerMemberName attribute to an optional parameter that has a default value.
ibid.
PropertyChanged가 널이 아닌 때에만 작동하도록 널 조건 연산자 ?.를 붙였다.
=>는 expression body definition이다. member => expression의 형태로 오른쪽의 표현식의 값을 반환한다. 화살표의 방향대로 왼쪽의 것을 오른쪽으로 반환하는 게 아니다.
The return type of expression must be implicitly convertible to the member’s return type.
Lambda expression (=>) operator defines a lambda expression