Reputation: 132
I am creating app in windows form. Below mentioned is structure of my list that I am going to bind to DataGridView. I have main list(Student) and inside main list, I have child list(Book) that is to be bind to DataGrid View. So, main list will have Id(int), Name(string) and lstBk(list which is child list).
public class Student
{
public int ID { get; set; }
public string Name { get; set; }
public List<Book> lstBk { get; set; }
}
public class Book
{
public int ID { get; set; }
public string Name{ get; set; }
}
Whenever I bind list to datagrid view, I am getting Id and Name only but not lstBk in grid view row. How do I get lstBk after ID and Name in datagrid view?
List<Book> lst = new List<Book>();
lst.Add(new Book() { ID= 1, Name ="Book 1" } );
lst.Add(new Book() { ID = 2, Name = "Book 2" });
lst.Add(new Book() { ID = 3, Name = "Book 3" });
List<Student> lstUD = new List<Student>();
lstUD.Add(new Student() { ID = 1, Name = "First Name1", lstBk = lst });
lstUD.Add(new Student() { ID = 2, Name = "First Name2", lstBk = lst });
dataGridView1.DataSource = lstUD;
Upvotes: 0
Views: 2192
Reputation: 9479
One possible solution is to “flatten” the Book
list. If we override the Books
ToString
method to output the books ID
and Name
... then we could then add a property to the Student
class that creates a single string from all the Books
in the list. Something like…
Book Class…
public class Book {
public int ID { get; set; }
public string Name { get; set; }
public override string ToString() {
return ID + " - " + Name;
}
}
Then create a new string
property ListOfBooks
in the Student Class. This will get shown in the grid. Something like...
public class Student {
public int ID { get; set; }
public string Name { get; set; }
public List<Book> lstBk { get; set; }
public string ListOfBooks {
get {
return string.Join(", ", lstBk);
}
}
}
This will put all the books from the list into a single cell in the grid. If there is too much data in the cell, then I would suggest using a master-detail with two grids. One for the student and another to display the books from the “selected” student in the “student/Master” grid.
Using a Master-Detail with two grids.
Create a new winforms project, drop a couple of DataGridView
s onto the form and the code below should demonstrate one way to implement a Master-Detail using the classes you have posted.
In this case, the Book
ToString
override is obviously not needed in addition to the added ListOfBooks
property in the Student
class. They may look like the original post…
public class Book {
public int ID { get; set; }
public string Name { get; set; }
}
public class Student {
public int ID { get; set; }
public string Name { get; set; }
public List<Book> lstBk { get; set; }
}
We will need some mechanism to “signal” when the user “selects” a different cell in the “Student/Master” grid. For this, we will wire up the grids SelectionChanged
event. In that event, the code "cast" the selected Student
in the grid to a Student
object, then uses the Students
lstBk
list to display into the “Book/Details” grid. This event may look something like below…
private void dataGridView1_SelectionChanged(object sender, EventArgs e) {
Student student = (Student)dataGridView1.CurrentRow.DataBoundItem;
dataGridView2.DataSource = student.lstBk;
}
When the grids are loaded, the details grid is filled using the first row in the master grid as in most cases, this is the default selected cell.
To complete this example, 10 Students
are added to the “Student/Master” grid such that each student has a random number of books between 1 and 6.
List<Student> AllStudents;
Random rand;
public Form1() {
InitializeComponent();
dataGridView1.SelectionChanged += new EventHandler(dataGridView1_SelectionChanged);
AllStudents = new List<Student>();
rand = new Random();
}
private void Form1_Load(object sender, EventArgs e) {
for (int i = 1; i < 11; i++) {
AllStudents.Add(GetStudent(i, "Student_" + i + 1));
}
dataGridView1.DataSource = AllStudents;
dataGridView2.DataSource = AllStudents[0].lstBk;
}
private Student GetStudent(int studentID, string name) {
int numberOfBooks = rand.Next(1, 7);
int bookNumber;
List<Book> books = new List<Book>();
for (int i = 0; i < numberOfBooks; i++) {
bookNumber = rand.Next(1, 10000);
books.Add(new Book { ID = bookNumber, Name = "Book" + bookNumber });
}
return new Student { ID = studentID, Name = name, lstBk = books };
}
I hope this makes sense.
Upvotes: 1