WinFormでDataGridViewにList <T>をバインド


91

クラスがあります

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

List<Person>いくつかのアイテムを追加します。リストはmyにバインドされてい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;

問題はない。myGrid2つの行が表示されますが、新しいアイテムをpersonsリストに追加しても、myGrid更新された新しいリストは表示されません。前に追加した2行のみが表示されます。

それで問題は何ですか?

毎回再バインドはうまくいきます。しかしDataTable、グリッドにバインドするとき、変更を加えるたびDataTableにReBindする必要はありませんmyGrid

毎回再バインドせずに解決するにはどうすればよいですか?

回答:


187

リストは実装されない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;

それはあなたがaswellのIListおよびその他のインタフェースを使用できることを述べている:msdn.microsoft.com/en-us/library/...
Pacane

4
@Pacane:もちろん可能ですが、DataGridViewはデータソースに変更があるかどうかを知る必要があります。OneBindingListを使用する方法は、基になるリストが変更された場合にイベントを発生させます。もう1つの方法はBindingSource、Rowを追加または削除するたびにaを使用してResetBinding()を呼び出すことですが、これにより作業が増えます。あなたがプロパティの変更についてのグリッドを知らせたい場合、最も簡単な方法は、実装することであるINotifyPropertyChanged
ユルゲン・Steinblock

5
リストをdatagridview datasourceプロパティに直接バインドできるので、なぜBindingListとBindingSourceを使用したのですか。ここで使用されているBindingListおよびBindingSource uの重要性について説明します。ありがとう
Mou

5
@Mou必要に応じて、DataGridをにバインドできList<T>ます。ただし、プログラムでリストに項目を追加した場合、リストは暗黙指定しないため、DataGridViewはそれを認識しませんIBindingList。BindingSourceについて:私はwinformsを頻繁に使用しており、BindingSource-FULLSTOP以外にはバインドしていません。詳細を追加することは、コメントとしては多すぎますが、BindingSource不利な点はありません。私はここまで行って言うAnyone who does not use a BindingSource for binding has not fully understood windows forms databindings
ユルゲンスタインブロック2015

4
@CraigBrett BindingSourceデータソースとGUIの間のブリッジとして検討してください。データバインディングに関連する多くの問題を解決します。データをリロードしますか?bindingSource.DataSourceすべてのコントロールを再バインドする代わりに、新しいコレクションに設定するだけです。DataSourceはnullにできますか?設定するbindingSource.DataSource = typeof(YourClass)あなたが編集可能なグリッドを持つようにしたいが、あなたのデータソースは、パラメータなしのコンストラクタを持っていませんか?bindingSource.AddingNewイベントを実装し、自分でオブジェクトを作成するだけです。使用中にマイナス面を経験したことはありませんBindingSourceが、多くのメリットがあります。
ユルゲン・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、2015

2

はい、INotifyPropertyChangedインターフェイスを実装することで、再バインドなしで実行できます。

かなりシンプルな例がここにあります、

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


1
INotifyPropertyChangedDataGridView を実装すると、バックグラウンドで発生するすべてのプロパティの変更が表示されますが、ソースから行を追加または削除するかどうかはわかりません。この目的のためにIBindingListインターフェースがあり、便宜上、BindingList<T>すでにそれを実装しているが、ソート/フィルタリングはサポートしていません。
ユルゲン・Steinblock

1
はい、同意します。そのため、ObservableCollection <T>を使用できると思います。どう思いますか?
Dev 2013年

0

追加する新しいアイテムをpersons追加した後:

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

datagridの下にdataSourceプロパティが表示されません。使用方法を教えてください。
RSB、2015

1
この提案は問題を引き起こす可能性があります。たとえば、グリッド内のアイテムをクリックすると、その時点ではデータソースがnullであるため、IndexOutOfRangeExceptionが発生する場合があります。他の回答が示すように、最初にBindingListにバインドし、オブジェクトにINotifyPropertyChangedを実装する方が賢明です
steve

次の行でnullすぐに割り当てる場合、それを割り当てる意味は何personsですか?
Rufus L

0

これは正確には私が抱えていた問題ではありませんが、任意のタイプのBindingListを同じタイプのListに変換しようとしている場合は、次のようになります。

var list = bindingList.ToDynamicList();

また、動的タイプのBindingListsをDataGridView.DataSourceに割り当てる場合は、最初にそれをIBindingListとして宣言して、上記が機能するようにします。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.