2009-08-04 1 views
47

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

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

public class FileName 
    { 
     private string _value; 

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

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

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

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

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

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

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

Спасибо

+0

Следует отметить, что в сетке будут отображаться только те общие поля в вашем объекте, которые являются свойствами.Другими словами, они должны иметь {get; задавать; } определены или они будут проигнорированы. – Shane

ответ

69

Используйте 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 
} 
+1

Дксон, ты спас меня; это сработало. Как я не мог увидеть «DataPropertyName» столбца? Мне плохо, когда я спрашивал такую ​​простую вещь, я должен был ее увидеть. Единственный вопрос, который у меня есть, - это когда я действительно должен использовать BindingSource, поскольку, кажется, все работает без него; но это то, что я узнаю вовремя, с практикой. –

+2

Вы должны использовать BindingSource, когда вам действительно нужна функциональность источника BindingSource. Обычное использование BindingSource - это когда пользователь должен делать некоторые входы на форме, и в этом случае вы можете привязать BindingSource к нескольким элементам управления одновременно. Существует гораздо больше возможностей BindingSource, но когда вам это действительно не нужно, используйте более простой подход, например BindingList. – sloth

+1

Привет, ребята, это именно то, что я искал сегодня. Наверное, спас мне час. Благодаря! –

3

Вместо того, чтобы создать новый класс контейнера можно использовать 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

10

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

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

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

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

для получения дополнительной информации вы можете посетить эту страницу Bind List of Class objects as Datasource to DataGridView

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

+1

Ваша ссылка мертва. Не могли бы вы предоставить другой источник? – Scorpion

+1

Зачем вы делаете вызов 'filelist.ToArray()' и имеете накладные расходы на выделение нового массива? Я считаю, что 'gvFilesOnServer.DataSource = filelist;' будет достаточно. Вызов '.ToArray()' в списке кажется ненужным накладным. –

1

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

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

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

6

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

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

Вы только что спасли мне часы отладки. СПАСИБО! –

 Смежные вопросы

  • Нет связанных вопросов^_^