2009-08-04 57 views
47

Tôi dường như đang chạy vòng tròn và đã làm như vậy trong những giờ qua.Cách liên kết danh sách với dataGridView?

Tôi muốn điền một khung nhìn dữ liệu từ một chuỗi các chuỗi. Tôi đã đọc nó không thể trực tiếp, và tôi cần tạo một kiểu tùy chỉnh chứa chuỗi như là một thuộc tính công cộng. Vì vậy, tôi đã thực hiện một lớp học:

public class FileName 
    { 
     private string _value; 

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

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

đây là lớp chứa và chỉ đơn giản là có thuộc tính với giá trị của chuỗi. Tất cả những gì tôi muốn bây giờ là chuỗi xuất hiện trong datagridview, khi tôi liên kết nguồn dữ liệu của nó với một Danh sách.

Ngoài ra tôi có phương pháp này, BindGrid() mà tôi muốn điền vào datagridview với. Đây là:

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

Cuối cùng, vấn đề: mảng chuỗi điền ok, danh sách được tạo ok, nhưng tôi nhận được một cột trống trong chế độ xem dữ liệu. Tôi cũng đã thử nguồn dữ liệu = danh sách <> trực tiếp, thay vì = bindingsource, vẫn không có gì.

Tôi thực sự đánh giá cao lời khuyên, điều này đã khiến tôi phát điên.

Cảm ơn bạn

+0

Một điều cần lưu ý, chỉ những trường công khai trong đối tượng của bạn là thuộc tính sẽ hiển thị trong lưới.Nói cách khác, họ cần phải có {get; bộ; } được xác định hoặc chúng sẽ bị bỏ qua. – Shane

Trả lời

69

Sử dụng một BindingList và thiết lập DataPropertyName -Property của cột.

Hãy thử như sau:

... 
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 bạn đã cứu tôi; điều này làm việc. Làm thế nào tôi có thể không nhìn thấy "DataPropertyName" của cột? Tôi cảm thấy xấu vì đã hỏi một điều đơn giản như vậy, tôi đáng lẽ đã thấy nó. Câu hỏi duy nhất tôi vẫn có là khi tôi thực sự nên sử dụng một BindingSource, vì mọi thứ dường như hoạt động mà không có nó; nhưng đó là những gì tôi sẽ tìm ra trong thời gian, với thực hành. –

+2

Bạn nên sử dụng BindingSource khi bạn thực sự cần chức năng của một BindingSource. Việc sử dụng BindingSource phổ biến là khi người dùng phải thực hiện một số đầu vào trên một biểu mẫu trong trường hợp đó bạn có thể ràng buộc BindingSource với nhiều Điều khiển cùng một lúc. Có nhiều hơn một BindingSource có thể làm, nhưng khi bạn thực sự không cần nó, hãy sử dụng một cách tiếp cận đơn giản hơn như BindingList. – sloth

+1

Chúc mừng các bạn, đây chính xác là những gì tôi đang tìm kiếm ngày hôm nay. Có lẽ đã cứu tôi một giờ rối tung. Cảm ơn! –

3

Thay vì tạo ra các lớp container mới, bạn có thể sử dụng một 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; 

Thông tin thêm về vấn đề này, bạn có thể tìm thấy ở đây: http://psworld.pl/Programming/BindingListOfString

10

có thể hơi muộn nhưng hữu ích cho tương lai. nếu bạn không yêu cầu để thiết lập các thuộc tính tùy chỉnh của tế bào và chỉ quan tâm với văn bản tiêu đề và giá trị của ô sau đó mã này sẽ giúp bạn

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

và sau đó bạn có thể liên kết Danh sách như nguồn dữ liệu như

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

để biết thêm thông tin, bạn có thể truy cập trang này Bind List of Class objects as Datasource to DataGridView

hy vọng điều này sẽ giúp bạn.

+1

Liên kết của bạn đã chết. Bạn có thể cung cấp một nguồn khác không? – Scorpion

+1

Tại sao bạn sẽ thực hiện cuộc gọi 'filelist.ToArray()' và có phí phân bổ một mảng mới? Tôi tin rằng 'gvFilesOnServer.DataSource = filelist;' sẽ là đủ. Gọi '.ToArray()' trên một List có vẻ như không cần thiết. –

1

Sử dụng DataTable hợp lệ với tên người dùng927524 đã nêu. Bạn cũng có thể làm điều đó bằng cách thêm hàng bằng tay, mà không yêu cầu thêm một lớp gói cụ thể:

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

Trong mọi trường hợp, nhờ user927524 cho thanh toán bù trừ hành vi kỳ lạ này !!

6

Tôi biết điều này là cũ, nhưng điều này đã treo tôi lên một lúc. Các thuộc tính của đối tượng trong danh sách của bạn phải là "thuộc tính" thực sự, không chỉ các thành viên công khai.

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

Bạn vừa lưu lại số giờ gỡ lỗi. CẢM ƠN BẠN! –

Các vấn đề liên quan