Tengo un simple List<string>
y me gustaría que se muestre en una DataGridView
columna.
Si la lista contendría objetos más complejos, simplemente establecería la lista como el valor de su DataSource
propiedad.
Pero al hacer esto:
myDataGridView.DataSource = myStringList;
Recibo 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?
c#
binding
datagridview
Agnieszka
fuente
fuente
DataPropertyName
de la columna debe serValue
Prueba esto:
IList<String> list_string= new List<String>(); DataGridView.DataSource = list_string.Select(x => new { Value = x }).ToList(); dgvSelectedNode.Show();
Espero que esto ayude.
fuente
List.ConvertAll(x => new { Value = x});
.Lo siguiente debería funcionar siempre que esté vinculado a cualquier cosa que implemente IEnumerable <string>. Vinculará la columna directamente a la cadena en sí, en lugar de a una ruta de propiedad de ese objeto de cadena.
<sdk:DataGridTextColumn Binding="{Binding}" />
fuente
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 no funciona, aquí está el contenido:
(..) Los valores que se muestran en la tabla representan la longitud de las cadenas en lugar de los valores de la cadena (!) Puede parecer extraño, pero así es como funciona el mecanismo de enlace de forma predeterminada: dado un objeto, intentará enlazar con la primera propiedad de ese objeto (la primera propiedad que puede encontrar). Cuando se pasa una instancia, la clase String, la propiedad a la que se une es String.Length, ya que no hay otra propiedad que proporcione la cadena real.
Eso significa que para que nuestro enlace sea correcto, necesitamos un objeto contenedor que expondrá 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<StringWrapper> testData = new List<StringWrapper>(); // 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 esperaba, requiere bastantes líneas de código (principalmente para convertir la lista de cadenas a la lista de envoltorios de cadenas).
Podemos mejorar esta solución usando LINQ y tipos anónimos; usaremos 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<string> strings) { var values = from data in strings select new { Value = data }; return values.ToList(); }
De esta manera podemos reutilizar el código llamando a un método único en cualquier colección de cadenas:
fuente
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
fuente
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:
Configure DataGridView (aquí "Ver") en modo virtual, cree la columna que necesita y anule / registre 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 puede simplemente asignar su lista a DataGridView:
fuente
Prueba esto :
//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); }
fuente
Una alternativa es usar una nueva función auxiliar que tomará valores de List y se actualizará en DataGridView de la siguiente manera:
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; }
Entonces podemos llamar a esta función de la siguiente manera:
DisplayStringListInDataGrid(<nameOfListWithStrings>, ref <nameOfDataGridViewToDisplay>, <nameToBeGivenForTheNewColumn>);
fuente