web-dev-qa-db-fra.com

Comment lier une liste à dataGridView?

Il me semble que je tourne en rond depuis les dernières heures.

Je veux remplir un datagridview à partir d'un tableau de chaînes. J'ai lu que ce n'est pas possible directement et que je dois créer un type personnalisé qui contient la chaîne en tant que propriété publique. Alors j'ai fait un cours:

public class FileName
    {
        private string _value;

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

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

c'est la classe conteneur, et elle a simplement une propriété avec la valeur de la chaîne. Tout ce que je veux maintenant, c'est que cette chaîne apparaisse dans le datagridview, lorsque je lie sa source de données à une liste.

De plus, j'ai cette méthode, BindGrid () avec laquelle je veux remplir le datagridview. C'est ici:

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

Enfin, le problème: le tableau de chaînes se remplit bien, la liste est créée correctement, mais je reçois une colonne vide dans le datagridview. J'ai aussi essayé datasource = list <> directement, au lieu de = bindingsource, toujours rien.

J'apprécierais vraiment un conseil, cela m'a rendu fou.

49
Amc_rtty

Utilisez un BindingList et définissez la propriété DataPropertyName - de la colonne.

Essayez ce qui suit:

...
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 
}
72
sloth

peut être un peu en retard mais utile pour le futur. si vous n'avez pas besoin de définir les propriétés personnalisées de la cellule et ne vous préoccupez que du texte d'en-tête et de la valeur de la cellule, ce code vous aidera

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

et ensuite vous pouvez lier List as datasource comme

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

pour plus d'informations, vous pouvez visiter cette page Lier une liste d'objets de classe en tant que source de données à DataGridView

j'espère que ceci vous aidera.

12
Nasir Mahmood

Je sais que c'est vieux, mais cela m'a suspendu pendant un moment. Les propriétés de l'objet dans votre liste doivent être des "propriétés" réelles, pas seulement des membres publics.

public class FileName
{        
     public string ThisFieldWorks {get;set;}
     public string ThisFieldDoesNot;
}
7
Kevin Finck

Au lieu de créer la nouvelle classe Container, vous pouvez utiliser 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;

Vous trouverez plus d'informations sur ce problème ici: http://psworld.pl/Programming/BindingListOfString

3
PsCraft

L'utilisation de DataTable est valide comme indiqué par user927524. Vous pouvez également le faire en ajoutant des lignes manuellement, ce qui ne nécessitera pas d'ajouter une classe de wrapping spécifique:

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

Dans tous les cas, merci à l'utilisateur927524 d'avoir effacé ce comportement étrange !!

1
user3214451