How to bind a List<string> to a DataGridView control?

C#BindingDatagridview

C# Problem Overview


I have a simple List<string> and I'd like it to be displayed in a DataGridView column.
If the list would contain more complex objects, simply would establish the list as the value of its DataSource property.

But when doing this:

myDataGridView.DataSource = myStringList;

I get a column called Length and the strings' lengths are displayed.

How to display the actual string values from the list in a column?

C# Solutions


Solution 1 - C#

Try this:

IList<String> list_string= new List<String>();
DataGridView.DataSource = list_string.Select(x => new { Value = x }).ToList();
dgvSelectedNode.Show();

I hope this helps.

Solution 2 - C#

Thats because DataGridView looks for properties of containing objects. For string there is just one property - length. So, you need a wrapper for a string like this

public class StringValue
{
    public StringValue(string s)
    {
        _value = s;
    }
    public string Value { get { return _value; } set { _value = value; } }
    string _value;
}

Then bind List<StringValue> object to your grid. It works

Solution 3 - C#

The following should work as long as you're bound to anything that implements IEnumerable<string>. It will bind the column directly to the string itself, rather than to a Property Path of that string object.

<sdk:DataGridTextColumn Binding="{Binding}" />

Solution 4 - C#

you can also use linq and anonymous types to achieve the same result with much less code as described here.

UPDATE: blog is down, here's the content:

(..) The values shown in the table represent the length of strings instead of string values (!) It may seem strange, but that’s how binding mechanism works by default – given an object it will try to bind to the first property of that object (the first property it can find). When passed an instance the String class the property it binds to is String.Length since there’s no other property that would provide the actual string itself.

That means that to get our binding right we need a wrapper object that will expose the actual value of a string as a property:

public class StringWrapper
    {
     string stringValue;
     public string StringValue { get { return stringValue; } set { stringValue = value; } }
     
     public StringWrapper(string s)
     {
     StringValue = s;
     }
  }   
    
   List<StringWrapper> testData = new List<StringWrapper>();
    
   // add data to the list / convert list of strings to list of string wrappers
    
  Table1.SetDataBinding(testdata);

While this solution works as expected it requires quite a few lines of code (mostly to convert list of strings to the list of string wrappers).

We can improve this solution by using LINQ and anonymous types- we’ll use LINQ query to create a new list of string wrappers (string wrapper will be an anonymous type in our case).

 var values = from data in testData select new { Value = data };
     
 Table1.SetDataBinding(values.ToList());

The last change we’re going to make is to move the LINQ code to an extension method:

public static class StringExtensions
  {
     public static IEnumerable CreateStringWrapperForBinding(this IEnumerable<string> strings)
     {
     var values = from data in strings
     select new { Value = data };
     
     return values.ToList();
     }

This way we can reuse the code by calling single method on any collection of strings:

Table1.SetDataBinding(testData.CreateStringWrapperForBinding());

Solution 5 - C#

This is common issue, another way is to use DataTable object

DataTable dt = new DataTable();
dt.Columns.Add("column name");

dt.Rows.Add(new object[] { "Item 1" });
dt.Rows.Add(new object[] { "Item 2" });
dt.Rows.Add(new object[] { "Item 3" });

This problem is described in detail here: <http://www.psworld.pl/Programming/BindingListOfString>

Solution 6 - C#

You might run into performance issues when assigning really large lists through LINQ. Following solution is suitable for large lists and without subclassing String:

Set DataGridView (here "View") to virtual mode, create column you need and override / register for event CellValueNeeded

private void View_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
{
    // Optionally: check for column index if you got more columns
    e.Value = View.Rows[e.RowIndex].DataBoundItem.ToString();
}

then you can simply assign your list to DataGridView:

List<String> MyList = ...
View.DataSource = MyList;

Solution 7 - C#

Try this :

//i have a 
List<string> g_list = new List<string>();

//i put manually the values... (for this example)
g_list.Add("aaa");
g_list.Add("bbb");
g_list.Add("ccc");

//for each string add a row in dataGridView and put the l_str value...
foreach (string l_str in g_list)
{
    dataGridView1.Rows.Add(l_str);
}

Solution 8 - C#

An alternate is to use a new helper function which will take values from List and update in the DataGridView as following:

    private void DisplayStringListInDataGrid(List<string> passedList, ref DataGridView gridToUpdate, string newColumnHeader)
    {
        DataTable gridData = new DataTable();
        gridData.Columns.Add(newColumnHeader);

        foreach (string listItem in passedList)
        {
            gridData.Rows.Add(listItem);
        }

        BindingSource gridDataBinder = new BindingSource();
        gridDataBinder.DataSource = gridData;
        dgDataBeingProcessed.DataSource = gridDataBinder;
    }

Then we can call this function the following way:

    DisplayStringListInDataGrid(<nameOfListWithStrings>, ref <nameOfDataGridViewToDisplay>, <nameToBeGivenForTheNewColumn>);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionagnieszkaView Question on Stackoverflow
Solution 1 - C#Tamanna JainView Answer on Stackoverflow
Solution 2 - C#sinmView Answer on Stackoverflow
Solution 3 - C#jamisonLikeCodeView Answer on Stackoverflow
Solution 4 - C#Jarek KardasView Answer on Stackoverflow
Solution 5 - C#user1246920View Answer on Stackoverflow
Solution 6 - C#user3042599View Answer on Stackoverflow
Solution 7 - C#NeojtView Answer on Stackoverflow
Solution 8 - C#SudeepView Answer on Stackoverflow