Как привязать список к dataGridView? - PullRequest
49 голосов
/ 04 августа 2009

Кажется, я бегаю кругами и делал это в последние часы.

Я хочу заполнить сетку данных из массива строк. Я читал, что это невозможно напрямую, и что мне нужно создать пользовательский тип, который содержит строку как открытое свойство. Итак, я сделал класс:

public class FileName
    {
        private string _value;

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

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

это класс контейнера, и у него просто есть свойство со значением строки. Все, что я хочу сейчас - это чтобы эта строка появлялась в сетке данных, когда я связываю ее источник данных со списком.

Также у меня есть этот метод, BindGrid (), которым я хочу заполнить сетку данных. Вот оно:

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

Наконец, проблема: массив строк заполняется нормально, список создается нормально, но я получаю пустой столбец в представлении данных. Я также попробовал datasource = list <> напрямую, вместо = bindingsource, но ничего не вышло.

Буду очень признателен за совет, это сводит меня с ума.

Ответы [ 5 ]

72 голосов
/ 04 августа 2009

Используйте BindingList и установите DataPropertyName -Свойство столбца.

Попробуйте следующее:

...
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 
}
12 голосов
/ 21 декабря 2013

может быть немного поздно, но полезно для будущего. если вам не требуется устанавливать пользовательские свойства ячейки, а касаются только текста заголовка и значения ячейки, тогда этот код поможет вам

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

и затем вы можете связать List как источник данных как

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

для получения дополнительной информации вы можете посетить эту страницу Привязать список объектов класса в качестве источника данных к DataGridView

надеюсь, это поможет вам.

7 голосов
/ 18 ноября 2015

Я знаю, что это старый, но это повесило меня на некоторое время. Свойства объекта в вашем списке должны быть фактическими "свойствами", а не просто открытыми членами.

public class FileName
{        
     public string ThisFieldWorks {get;set;}
     public string ThisFieldDoesNot;
}
3 голосов
/ 18 октября 2012

Вместо создания нового класса Container вы можете использовать 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;

Подробнее об этой проблеме вы можете узнать здесь: http://psworld.pl/Programming/BindingListOfString

1 голос
/ 18 сентября 2015

Использование DataTable действительно как заявлено user927524. Вы также можете сделать это, добавив строки вручную, что не потребует добавления определенного класса переноса:

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

В любом случае, спасибо user927524 за устранение этого странного поведения !!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...