WinForm의 DataGridView에 List <T> 바인딩


91

나는 수업이있다

class Person{
      public string Name {get; set;}
      public string Surname {get; set;}
}

그리고 List<Person>어떤에 나는 일부 항목을 추가 할 수 있습니다. 목록은 내 DataGridView.

List<Person> persons = new List<Person>();
persons.Add(new Person(){Name="Joe", Surname="Black"});
persons.Add(new Person(){Name="Misha", Surname="Kozlov"});
myGrid.DataSource = persons;

문제 없습니다. myGrid두 행을 표시하지만 내 persons목록에 새 항목을 추가하면 myGrid새 업데이트 된 목록이 표시되지 않습니다. 이전에 추가 한 두 행만 표시됩니다.

그래서 무엇이 문제입니까?

매번 리 바인딩이 잘 작동합니다. 그러나 내가 DataTable그리드에 바인딩 할 때마다 변경 사항이 DataTable있을 때마다 ReBind 할 필요가 없습니다 myGrid.

매번 다시 바인딩하지 않고 해결하는 방법은 무엇입니까?

답변:


188

목록이 구현되지 않으므로 IBindingList그리드가 새 항목에 대해 알지 못합니다.

BindingList<T>대신 DataGridView를에 바인딩하십시오 .

var list = new BindingList<Person>(persons);
myGrid.DataSource = list;

그러나 나는 더 나아가 당신의 그리드를 BindingSource

var list = new List<Person>()
{
    new Person { Name = "Joe", },
    new Person { Name = "Misha", },
};
var bindingList = new BindingList<Person>(list);
var source = new BindingSource(bindingList, null);
grid.DataSource = source;

IList 및 기타 인터페이스도 사용할 수 있다고 말합니다. msdn.microsoft.com/en-us/library/…
Pacane

4
@Pacane : 물론 가능하지만 DataGridView는 데이터 소스에 변경 사항이 있는지 알아야합니다. OneBindingList를 사용하는 방법은 기본 목록이 변경 될 경우 이벤트를 발생시킵니다. 또 다른 방법 BindingSource은를 사용 하고 행을 추가 / 삭제할 때마다 ResetBinding ()을 호출하는 것입니다. 그리드에 속성 변경에 대해 알리고 싶다면 가장 쉬운 방법은 구현하는 것입니다INotifyPropertyChanged
Jürgen Steinblock

5
목록을 datagridview 데이터 소스 속성에 직접 바인딩 할 수 있기 때문에 BindingList 및 BindingSource를 사용하는 이유는 무엇입니까? 여기서 사용 된 BindingList 및 BindingSource u의 중요성에 대해 설명합니다. 감사합니다
Mou

5
@Mou List<T>원하는 경우 DataGrid를에 바인딩 할 수 있습니다 . 그러나 프로그래밍 방식으로 List에 항목을 추가하면 List가 묵시적이지 않기 때문에 DataGridView는 그것에 대해 알지 못합니다 IBindingList. BindingSource와 관련하여 : 나는 winforms를 많이 사용하며 BindingSource-FULLSTOP 이외의 다른 것에 바인딩하지 않습니다. 더 많은 세부 사항을 추가하는 것은 의견에 너무 많지만 BindingSource단점없이 제공 할 것이 너무 많습니다 . 지금까지 가서 말할 것Anyone who does not use a BindingSource for binding has not fully understood windows forms databindings
위르겐 Steinblock에게

4
@CraigBrett BindingSource데이터 소스와 GUI 사이의 다리로 간주하십시오 . 많은 데이터 바인딩 관련 문제를 해결합니다. 데이터를 다시로드 하시겠습니까? bindingSource.DataSource모든 컨트롤을 다시 바인딩하는 대신 새 컬렉션으로 설정 하기 만하면됩니다 . 데이터 소스가 null 일 수 있습니까? 설정 bindingSource.DataSource = typeof(YourClass)당신은 편집 가능한 그리드를 갖고 싶어하지만 데이터 소스는 매개 변수가없는 생성자가 없습니다? bindingSource.AddingNew이벤트를 구현 하고 개체를 직접 만드십시오. 나는 사용하는 동안 단점을 경험 한 적이 BindingSource없지만 많은 이점이 있습니다.
Jürgen Steinblock

4

목록에 새 요소를 추가 할 때마다 그리드를 다시 바인딩해야합니다. 다음과 같은 것 :

List<Person> persons = new List<Person>();
persons.Add(new Person() { Name = "Joe", Surname = "Black" });
persons.Add(new Person() { Name = "Misha", Surname = "Kozlov" });
dataGridView1.DataSource = persons;

// added a new item
persons.Add(new Person() { Name = "John", Surname = "Doe" });
// bind to the updated source
dataGridView1.DataSource = persons;

datagrid 아래에 dataSource 속성이 표시되지 않는데 어떻게 사용하는지 알려주세요.
RSB

2

예, INotifyPropertyChanged 인터페이스를 구현하여 리 바인딩없이 수행 할 수 있습니다.

여기에 꽤 간단한 예제가 있습니다.

http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx


1
충분하지 않습니다 INotifyPropertyChanged. DataGridView 를 구현 하면 백그라운드에서 발생하는 모든 속성 변경 사항이 표시되지만 소스에서 행을 추가 / 삭제하는지 여부는 알 수 없습니다. 이를 위해 IBindingList인터페이스와 편의를 위해 BindingList<T>이미이를 구현하지만 정렬 / 필터링을 지원하지 않는 구현이 있습니다.
Jürgen Steinblock

1
네, 동의합니다. 그래서 나는 이것을 위해 ObservableCollection <T>를 사용할 수 있다고 생각합니다. 어떻게 생각해?
Dev

0

추가 할 새 항목을 persons추가 한 후 :

myGrid.DataSource = null;
myGrid.DataSource = persons;

datagrid 아래에 dataSource 속성이 표시되지 않습니다. 어떻게 사용하는지 알려주세요.
RSB

1
이 제안은 문제를 일으킬 수 있습니다. 예를 들어 그리드의 항목을 클릭하면 해당 지점에서 데이터 소스가 null이므로 IndexOutOfRangeException이 발생할 수 있습니다. 처음에는 BindingList 에 바인딩하고 다른 답변이 나타내는 것처럼 개체에 INotifyPropertyChanged 를 구현 하는 것이 현명 할 것입니다.
steve

다음 줄에 null즉시 할당하면 할당의 포인트는 무엇입니까 persons?
Rufus L

0

이것은 정확히 내가 가진 문제는 아니지만 누군가 모든 유형의 BindingList를 동일한 유형의 List로 변환하려는 경우 다음과 같이 수행됩니다.

var list = bindingList.ToDynamicList();

또한 동적 형식의 BindingList를 DataGridView.DataSource에 할당하는 경우 먼저 IBindingList로 선언해야 위의 작업이 수행됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.