2009-08-04 21 views
47

Parece que estoy corriendo en círculos y lo he estado haciendo en las últimas horas.Cómo enlazar la lista a dataGridView?

Quiero rellenar una vista de cuadrícula de datos a partir de una matriz de cadenas. He leído que no es posible directamente, y que necesito crear un tipo personalizado que mantenga la cadena como una propiedad pública. Así que hice una clase:

public class FileName 
    { 
     private string _value; 

     public FileName(string pValue) 
     { 
      _value = pValue; 
     } 

     public string Value 
     { 
      get 
      { 
       return _value; 
      } 
      set { _value = value; } 
     } 
    } 

esta es la clase de contenedor, y simplemente tiene una propiedad con el valor de la cadena. Todo lo que quiero ahora es que la cadena aparezca en la vista de cuadrícula de datos, cuando vinculo su fuente de datos a una lista.

También tengo este método, BindGrid() con el que quiero rellenar la cuadrícula de datos. Aquí está:

private void BindGrid() 
    { 
     gvFilesOnServer.AutoGenerateColumns = false; 

     //create the column programatically 
     DataGridViewTextBoxColumn colFileName = new DataGridViewTextBoxColumn(); 
     DataGridViewCell cell = new DataGridViewTextBoxCell(); 
     colFileName.CellTemplate = cell; colFileName.Name = "Value"; 
     colFileName.HeaderText = "File Name"; 
     colFileName.ValueType = typeof(FileName); 

     //add the column to the datagridview 
     gvFilesOnServer.Columns.Add(colFileName); 

     //fill the string array 
     string[] filelist = GetFileListOnWebServer(); 

     //try making a List<FileName> from that array 
     List<FileName> filenamesList = new List<FileName>(filelist.Length); 
     for (int i = 0; i < filelist.Length; i++) 
     { 
      filenamesList.Add(new FileName(filelist[i].ToString())); 
     } 

     //try making a bindingsource 
     BindingSource bs = new BindingSource(); 
     bs.DataSource = typeof(FileName); 
     foreach (FileName fn in filenamesList) 
     { 
      bs.Add(fn); 
     } 
     gvFilesOnServer.DataSource = bs; 
    } 

Por último, el problema: la matriz de cadenas se llena bien, la lista se crea bien, pero me sale una columna vacía en el DataGridView. También probé datasource = list <> directamente, en lugar de = bindingsource, todavía nada.

Realmente agradecería un consejo, esto me ha estado volviendo loco.

Gracias

+0

Una cosa a tener en cuenta, solo los campos públicos en su objeto que son propiedades se mostrarán en la cuadrícula.En otras palabras, necesitan tener {get; conjunto; } definido o se ignorarán. – Shane

Respuesta

69

utiliza un BindingList y establecer el DataPropertyName-Propiedades de la columna.

intente lo siguiente:

... 
private void BindGrid() 
{ 
    gvFilesOnServer.AutoGenerateColumns = false; 

    //create the column programatically 
    DataGridViewCell cell = new DataGridViewTextBoxCell(); 
    DataGridViewTextBoxColumn colFileName = new DataGridViewTextBoxColumn() 
    { 
     CellTemplate = cell, 
     Name = "Value", 
     HeaderText = "File Name", 
     DataPropertyName = "Value" // Tell the column which property of FileName it should use 
    }; 

    gvFilesOnServer.Columns.Add(colFileName); 

    var filelist = GetFileListOnWebServer().ToList(); 
    var filenamesList = new BindingList<FileName>(filelist); // <-- BindingList 

    //Bind BindingList directly to the DataGrid, no need of BindingSource 
    gvFilesOnServer.DataSource = filenamesList 
} 
+1

Dkson me has salvado; esto funcionó. ¿Cómo no puedo ver el "Nombre de la propiedad de datos" de la columna? Me siento mal por preguntar algo tan simple, debería haberlo visto. La única pregunta que aún tengo es cuando realmente debería hacer uso de un BindingSource, ya que las cosas parecen funcionar sin él; pero eso es lo que descubriré a tiempo, con práctica. –

+2

Debe utilizar un BindingSource cuando realmente necesite la funcionalidad de un BindingSource. Un uso común de BindingSource es cuando el usuario tiene que hacer algunas entradas en un formulario en cuyo caso puede vincular el BindingSource a múltiples controles a la vez. BindingSource puede hacer mucho más, pero cuando en realidad no lo necesita, use un enfoque más simple como BindingList. – sloth

+1

Saludos chicos, esto era exactamente lo que estaba buscando hoy. Probablemente me salvó una hora de perder el tiempo. ¡Gracias! –

3

En lugar de crear una nueva clase de contenedores se puede utilizar un dataTable.

DataTable dt = new DataTable(); 
dt.Columns.Add("My first column Name"); 

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

myDataGridView.DataSource = dt; 

Más acerca de este problema se puede encontrar aquí: http://psworld.pl/Programming/BindingListOfString

10

puede ser poco tarde, pero útil para el futuro. Si no se requiere para establecer las propiedades personalizadas de la célula y única preocupación con el texto de cabecera y el valor de la celda a continuación, este código le ayudará a

public class FileName 
{   
    [DisplayName("File Name")] 
    public string FileName {get;set;} 
    [DisplayName("Value")] 
    public string Value {get;set;} 
} 

y luego se puede enlazar de lista como fuente de datos como

private void BindGrid() 
{ 
    var filelist = GetFileListOnWebServer().ToList();  
    gvFilesOnServer.DataSource = filelist.ToArray(); 
} 

para obtener más información, puede visitar esta página Bind List of Class objects as Datasource to DataGridView

Espero que esto le ayude.

+1

Su enlace está muerto. ¿Podrías proporcionar otra fuente? – Scorpion

+1

¿Por qué debería hacer la llamada 'filelist.ToArray()' y tener la sobrecarga de asignar una nueva matriz? Creo que 'gvFilesOnServer.DataSource = filelist;' sería suficiente. Llamar '.ToArray()' en una lista parece una sobrecarga innecesaria. –

1

El uso de DataTable es válido como se indicó en user927524. También puede hacerlo de forma manual mediante la adición de filas, que no requerirá agregar una clase específica de embalaje:

List<string> filenamesList = ...; 
foreach(string filename in filenamesList) 
     gvFilesOnServer.Rows.Add(new object[]{filename}); 

En cualquier caso, gracias user927524 para la limpieza de este comportamiento extraño !!

6

Sé que esto es viejo, pero esto me colgó por un tiempo. Las propiedades del objeto en su lista deben ser "propiedades" reales, no solo miembros públicos.

public class FileName 
{   
    public string ThisFieldWorks {get;set;} 
    public string ThisFieldDoesNot; 
} 
+0

Acabas de ahorrarme horas de depuración. ¡GRACIAS! –

Cuestiones relacionadas