[c#] BindingList와 DataGridView의 바인딩을 일시적으로 끊기

BindingList를 DataGridView에 바인딩한 뒤 잠깐 바인딩을 끊어야 할 때가 있다. 예를 들어 루프를 돌려 바인딩 리스트에 엘리먼트를 추가하는 경우 바인딩을 끊지 않으면 엘리먼트 하나가 추가될 때마다 데이터 그리드 뷰가 갱신되어 부하가 커진다.

간단하게 아래의 방법을 생각해 볼 수 있지만 무식하고 부하가 크고 데이터 그리드 뷰의 일부 설정들이 초기화된다.

DataGridView.DataSource = null;
DataGridView.DataSource = BindingList<T>;

BindingSource1.RaiseListChangedEvents 프라퍼티를 이용하면 간단하다.

아래의 예제에서 버튼 1을 클릭하면 바인딩이 일시적으로 멈추고 이어서 바인딩 리스트에 엘리먼트가 추가된다. 추가된 엘리먼트는 데이터 그리드 뷰에 출력되지 않는다. 버튼 2를 클릭하면 바인딩이 작동하며 추가된 엘리먼트가 출력된다. RaiseListChangedEvents를 true로 하는 것만으로는 이미 변경된 내용이 출력되지 않는다. ResetBindings 메서드를 이용하여 데이터 그리드 뷰를 갱신해야 한다. 데이터 스키마가 바뀐 때에 true를 넘기고 그냥 내용만 변경된 때에는 false로 설정한다.

class Class1
{
    public int Int { get; set; }
}

BindingList<Class1> Class1s = new();

BindingSource BindingSource1 = new();

private void Form1_Load(object sender, EventArgs e)
{
    BindingSource1.DataSource = Class1s;

    dataGridView1.DataSource = BindingSource1;
}

private void button1_Click(object sender, EventArgs e)
{
    BindingSource1.RaiseListChangedEvents = false;

    Class1 class1 = new();

    class1.Int = 1;

    Class1s.Add(class1);
}

private void button2_Click(object sender, EventArgs e)
{
    BindingSource1.RaiseListChangedEvents = true;

    BindingSource1.ResetBindings(false);
}

BindingSource.SuspendBinding 메서드는 데이터 그리드 뷰에는 먹지 않는다.

Controls that use complex data binding, such as the DataGridView control, update their values based on change events such as the ListChanged event, so calling SuspendBinding will not prevent them from receiving changes to the data source.
BindingSource.SuspendBinding Method