Binding a DataGridView to a Collection in C#
By FoxLearn 1/16/2025 6:22:09 AM 67
Before we get started with the collection, we need an object to hold the data.
For this example, I'll use a Book
class, which contains basic information about a book, such as title, author, and publication year.
public class Book { private string _title; private string _author; private int _year; public Book(string title, string author, int year) { _title = title; _author = author; _year = year; } public string Title { get { return _title; } set { _title = value; } } public string Author { get { return _author; } set { _author = value; } } public int Year { get { return _year; } set { _year = value; } } }
Now that we have the Book
class, we need a collection to store multiple Book
objects. I'll use a List<Book>
from the System.Collections.Generic
namespace:
List<Book> books = new List<Book>(); books.Add(new Book("The Catcher in the Rye", "J.D. Salinger", 1951)); books.Add(new Book("1984", "George Orwell", 1949)); books.Add(new Book("To Kill a Mockingbird", "Harper Lee", 1960));
Binding this List<Book>
to a DataGridView
is simple. All you need to do is set the DataSource
property of the DataGridView
to the List
:
_dgBooks.DataSource = books;
Once this is done, the DataGridView
will automatically create columns for each property of the Book
object, and a row will be generated for each Book
in the list. This creates one-way binding, where any changes made in the DataGridView
will reflect in the List<Book>
.
However, if you want changes in the Book
objects to be reflected in the DataGridView
, you'll need to implement the INotifyPropertyChanged
interface.
public class Book : INotifyPropertyChanged { private string _title; private string _author; private int _year; public event PropertyChangedEventHandler PropertyChanged; public Book(string title, string author, int year) { _title = title; _author = author; _year = year; } public string Title { get { return _title; } set { _title = value; this.NotifyPropertyChanged("Title"); } } public string Author { get { return _author; } set { _author = value; this.NotifyPropertyChanged("Author"); } } public int Year { get { return _year; } set { _year = value; this.NotifyPropertyChanged("Year"); } } private void NotifyPropertyChanged(string name) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); } }
However, there's a catch: the List<T>
class doesn't notify changes made to its contained objects. To resolve this, we can use the BindingList<T>
, which does support notifications when objects inside the collection change:
BindingList<Book> books = new BindingList<Book>(); books.Add(new Book("The Catcher in the Rye", "J.D. Salinger", 1951)); books.Add(new Book("1984", "George Orwell", 1949)); books.Add(new Book("To Kill a Mockingbird", "Harper Lee", 1960)); _dgBooks.DataSource = books;
Now, if any changes are made to a Book
object (even from an external thread or process), the DataGridView
will automatically reflect those changes.
Next, you may want to customize the column headers and bindings.
By default, the DataGridView
will automatically generate column names based on the property names, but you can disable that by setting AutoGenerateColumns
to false
and manually defining the columns.
_dgBooks.AutoGenerateColumns = false; DataGridViewTextBoxColumn titleColumn = new DataGridViewTextBoxColumn(); titleColumn.DataPropertyName = "Title"; titleColumn.HeaderText = "Book Title"; DataGridViewTextBoxColumn authorColumn = new DataGridViewTextBoxColumn(); authorColumn.DataPropertyName = "Author"; authorColumn.HeaderText = "Book Author"; DataGridViewTextBoxColumn yearColumn = new DataGridViewTextBoxColumn(); yearColumn.DataPropertyName = "Year"; yearColumn.HeaderText = "Publication Year"; _dgBooks.Columns.Add(titleColumn); _dgBooks.Columns.Add(authorColumn); _dgBooks.Columns.Add(yearColumn); BindingList<Book> books = new BindingList<Book>(); books.Add(new Book("The Catcher in the Rye", "J.D. Salinger", 1951)); books.Add(new Book("1984", "George Orwell", 1949)); books.Add(new Book("To Kill a Mockingbird", "Harper Lee", 1960)); _dgBooks.DataSource = books;
This will allow you to control the column headers and data property names.
The DataPropertyName
is bound to the property of the object (like Title
, Author
, or Year
), and the HeaderText
is what the user will see in the DataGridView's column header.
- How to fix 'Failure sending mail' in C#
- How to Parse a Comma-Separated String from App.config in C#
- How to convert a dictionary to a list in C#
- How to retrieve the Executable Path in C#
- How to validate an IP address in C#
- How to retrieve the Downloads Directory Path in C#
- C# Tutorial
- Dictionary with multiple values per key in C#