The problem you describe can be solved a couple of different ways. One is to “flatten” each List<Foo>. Basically this will flatten ALL the Foo items in a list into a “single” string. With this approach as I commented, you would end up with one column and each row would be a “flattened” List<Foo>. Each cell may have a different number of Foo items in the string.
In this case and as others, this may not be the desired result. Since you have a List of Lists, then a “Master-Detail" approach using two (2) grids may make things easier. In this approach, the first grid (master) would have one (1) column and each row would be a List<Foo>. Since we already know the grid will not display this LIST into a single cell AND we don’t want to “flatten” the list, then this is where the second (detail) grid comes into play. The first grid displays all the lists of Foo, and whichever “row” is selected, the second grid (detail) will display all the List<Foo> items.
An example may work best to show what I mean. First, we need to make an additional class. Reason being that is if we use a List<List<Foo>> as a DataSource to the master grid, it will show something like…

As shown the two columns are going to be the List “Capacity” and “Count.” This may work; however, it may be confusing to the user. That is why we want this other class. It is a simple “wrapper” around the List<Foo> and to display this we will add a “Name” property to this class. This will be displayed in the master grid.
Given the current modified Foo class…
public class Foo {
public string Value { get; set; }
public int Id { get; set; }
}
This FooList class may look something like…
public class FooList {
public string ListName { get; set; }
public List<Foo> TheFooList { get; set; }
}
A List<FooList> would display something like…

Now, when the user “selects” a row in the first “Master” grid, the second “Detail" grid will display all the Foo items in that list. A full example is below. Drop two grids onto a form and copy the code below to follow.
To help, a method that returns a List<Foo> where there are a random number of Foo items in each list. This method may look something like below with the global rand Random variable to get a random number of Foo items to add to the list in addition to setting a random Value for each Foo object.
Random rand = new Random();
private List<Foo> GettRandomNumberOfFooList() {
int numberOfFoo = rand.Next(2, 20);
List<Foo> fooList = new List<Foo>();
for (int i = 0; i < numberOfFoo; i++) {
fooList.Add(new Foo { Id = i, Value = rand.Next(1, 100).ToString() });
}
return fooList;
}
We can use this method to create a List<FooList> for testing. The master grids DataSource will be this list. Then, to determine which list to display in the details grid, we will simply use the selected FooList.TheFooList property.
Next, we need a trigger to know when to “change” the details data source. In this case I used the grids, RowEnter method to change the details grids data source.
Below is the code described above. The master grid will have 15 FooList items.
List<FooList> FooLists;
public Form1() {
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) {
FooLists = new List<FooList>();
for (int i = 0; i < 15; i++) {
FooLists.Add(new FooList { ListName = "Foo List " + (i + 1), TheFooList = GettRandomNumberOfFooList() });
}
dataGridView1.DataSource = FooLists;
dataGridView2.DataSource = FooLists[0].TheFooList;
}
private void dataGridView1_RowEnter(object sender, DataGridViewCellEventArgs e) {
dataGridView2.DataSource = FooLists[e.RowIndex].TheFooList;
}
This should produce something like...

Lastly, this is just an example and using a BindingList/BindingSource may make things easier. This is a very simple example of using a “Master-Detail” approach with a List of Lists.