¿Cómo vincular una Lista a un control DataGridView?

Tengo una List simple List y me gustaría que se muestre en una columna DataGridView .
Si la lista contendría objetos más complejos, simplemente establecería la lista como el valor de su propiedad DataSource .

Pero al hacer esto:

 myDataGridView.DataSource = myStringList; 

Obtengo una columna llamada Length y se muestran las longitudes de las cadenas.

¿Cómo mostrar los valores de cadena reales de la lista en una columna?

Eso es porque DataGridView busca propiedades de objetos que contienen. Para la cadena solo hay una propiedad – longitud. Entonces, necesitas un contenedor para una cadena como esta

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

A continuación, enlace el objeto List a su grilla. Funciona

Prueba esto:

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

Espero que esto ayude.

Lo siguiente debería funcionar siempre que estés obligado a cualquier cosa que implemente IEnumerable . Se vinculará la columna directamente a la cadena en sí, en lugar de a una ruta de propiedad de ese objeto de cadena.

  

también puede usar linq y tipos anónimos para lograr el mismo resultado con mucho menos código como se describe aquí .

ACTUALIZACIÓN: el blog está inactivo, aquí está el contenido:

(..) Los valores mostrados en la tabla representan la longitud de las cadenas en lugar de los valores de cadena (!) Puede parecer extraño, pero así es como funciona el mecanismo de vinculación por defecto, dado un objeto que intentará vincular a la primera propiedad de esa cadena objeto (la primera propiedad que puede encontrar). Cuando se pasa una instancia de la clase String, la propiedad a la que se une es String.Length, ya que no hay otra propiedad que proporcione la propia cadena.

Eso significa que para obtener nuestro enlace correcto necesitamos un objeto contenedor que exponga el valor real de una cadena como una propiedad:

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

Si bien esta solución funciona como se espera, requiere bastantes líneas de código (principalmente para convertir una lista de cadenas en la lista de envoltorios de cadenas).

Podemos mejorar esta solución utilizando LINQ y tipos anónimos: utilizaremos la consulta LINQ para crear una nueva lista de envoltorios de cadenas (el envoltorio de cadenas será un tipo anónimo en nuestro caso).

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

El último cambio que vamos a hacer es mover el código LINQ a un método de extensión:

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

De esta forma, podemos reutilizar el código llamando al método único en cualquier colección de cadenas:

 Table1.SetDataBinding(testData.CreateStringWrapperForBinding()); 

Este es un problema común, otra forma es usar el objeto DataTable

 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" }); 

Este problema se describe en detalle aquí: http://www.psworld.pl/Programming/BindingListOfString

Prueba esto :

 //i have a List g_list = new List(); //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); } 

Es posible que tenga problemas de rendimiento al asignar listas realmente grandes a través de LINQ. La siguiente solución es adecuada para listas grandes y sin subclases de cadenas:

Establezca DataGridView (aquí “Ver”) en modo virtual, cree la columna que necesita y anule / regístrese para el evento 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(); } 

entonces simplemente puede asignar su lista a DataGridView:

 List MyList = ... View.DataSource = MyList; 

Una alternativa es usar una nueva función auxiliar que tomará los valores de la Lista y la actualización en el DataGridView de la siguiente manera:

  private void DisplayStringListInDataGrid(List 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; } 

Entonces podemos llamar a esta función de la siguiente manera:

  DisplayStringListInDataGrid(, ref , );