如何将列表绑定到 dataGridView?

Posted

技术标签:

【中文标题】如何将列表绑定到 dataGridView?【英文标题】:How to bind list to dataGridView? 【发布时间】:2010-11-16 17:52:37 【问题描述】:

我似乎在兜圈子,在过去的几个小时里一直在这样做。

我想从一个字符串数组中填充一个 datagridview。我已经阅读了它不可能直接,并且我需要创建一个将字符串作为公共属性保存的自定义类型。于是我做了一个类:

public class FileName
    
        private string _value;

        public FileName(string pValue)
        
            _value = pValue;
        

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

这是容器类,它只是有一个带有字符串值的属性。我现在想要的只是当我将它的数据源绑定到列表时,该字符串出现在 datagridview 中。

我也有这个方法,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;
    

最后,问题:字符串数组填充正常,列表创建正常,但我在datagridview中得到一个空列。我也直接试过datasource=list,而不是=bindingsource,还是什么都没有。

非常感谢您的建议,这让我发疯了。

【问题讨论】:

有一点需要注意,只有对象中那些作为属性的公共字段才会在网格中呈现。换句话说,他们需要有 get;放; 定义,否则它们将被忽略。 【参考方案1】:

可能有点晚,但对未来很有用。如果您不需要设置单元格的自定义属性并且只关心标题文本和单元格值,那么此代码将为您提供帮助

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();

有关更多信息,您可以访问此页面Bind List of Class objects as Datasource to DataGridView

希望这会对你有所帮助。

【讨论】:

您的链接已失效。能否提供其他来源? 为什么要调用filelist.ToArray() 并承担分配新数组的开销?我相信gvFilesOnServer.DataSource = filelist; 就足够了。在 List 上调用 .ToArray() 似乎是不必要的开销。【参考方案2】:

我知道这是旧的,但这让我挂了一段时间。列表中对象的属性必须是实际的“属性”,而不仅仅是公共成员。

public class FileName
        
     public string ThisFieldWorks get;set;
     public string ThisFieldDoesNot;

【讨论】:

您刚刚为我节省了数小时的调试时间。谢谢!【参考方案3】:

使用 DataTable 是有效的,如 user927524 所述。 您也可以通过手动添加行来做到这一点,这不需要添加特定的包装类:

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

无论如何,感谢 user927524 清除这种奇怪的行为!!

【讨论】:

【参考方案4】:

您可以使用 dataTable 来代替创建新的 Container 类。

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

【讨论】:

【参考方案5】:

使用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 

【讨论】:

Dkson 你救了我;这行得通。我怎么看不到该列的“DataPropertyName”?问这么简单的事我觉得不好意思,我应该看到的。我唯一的问题是我什么时候应该真正使用 BindingSource,因为没有它似乎也能正常工作;但这就是我会及时发现的,通过练习。 当您真正需要 BindingSource 的功能时,您应该使用 BindingSource。 BindingSource 的一个常见用途是用户必须在表单上进行一些输入,在这种情况下,您可以一次将 BindingSource 绑定到多个控件。 BindingSource 可以做的事情还有很多,但是当您实际上不需要它时,请使用更简单的方法,例如 BindingList。 干杯伙计们,这正是我今天要找的。可能节省了我一个小时的时间。谢谢! 我认为初始化器上面的两行被交换了...应该是:DataGridViewCell cell = new DataGridViewTextBoxCell();DataGridViewTextBoxColumn colFileName = new DataGridViewTextBoxColumn()`

以上是关于如何将列表绑定到 dataGridView?的主要内容,如果未能解决你的问题,请参考以下文章

WPF中常用的表格控件都有哪些

Datagridview将Comboboxcolumns绑定到更改列表

将对象列表数据绑定到 WinForms DataGridView,但不显示某些公共属性

在C#里怎么将DataGridView控件和数据库的查询绑定起来啊。

DataGridView控件用法一:数据绑定

数据绑定期间如何在datagridview中自定义格式数据