DataGridViewColumn.DataPropertyName 属性

Posted

技术标签:

【中文标题】DataGridViewColumn.DataPropertyName 属性【英文标题】:DataGridViewColumn.DataPropertyName Property 【发布时间】:2011-01-14 08:09:24 【问题描述】:

我有一个 DataGridView 控件,我想用数据填充它。

我使用 DataSource 属性

// dgvDealAsset is DataGridView
        private void DealAssetListControl_Load(object sender, EventArgs e)
        
            dgvDealAssets.AutoGenerateColumns = false;
            dgvDealAssets.DataSource = DealAssetList.Instance.Values.ToList();

现在是第一个问题。我的集合类不仅包含可以使用 DataPropertyName 映射到列的简单类型。这是集合中包含的类。

class MyClass

  public String Name;
  MyOtherClass otherclass;


class MyOtherClass

 public String Name;

现在我将 MyClass 的属性绑定到列

col1.DataPropertyName = "Name"  // Ok 
col2.DataPropertyName = "otherclass" // Not OK - I will have empty cell

问题是我想显示 otherclass.Name 字段。但是如果我尝试写

col2.DataPropertyName = "otherclass.Name" 

我得到空单元格。

我尝试手动设置列

private void DealAssetListControl_Load(object sender, EventArgs e)

    dgvDealAssets.AutoGenerateColumns = false;
    dgvDealAssets.DataSource = DealAssetList.Instance.Values.ToList();

// iterate through rows and set the column manually
        foreach (DataGridViewRow row in dgvDealAssets.Rows)
        
            row.Cells["Column2"].Value = ((DealAsset)row.DataBoundItem).otherclass.Name;
        

但是这个 foreach 循环大约需要几分钟才能完成(2k 个元素)。如何解决这个问题?

【问题讨论】:

【参考方案1】:

DataGridView 不支持数据绑定到子属性。欲了解更多信息,请查看this post

我喜欢使用 CellFormatting 事件的解决方案。

【讨论】:

【参考方案2】:

问题 nr.1:

尝试执行以下操作:

    从 Object 扩展 MyOtherClass(可能不需要此步骤)

    并覆盖或创建方法 ToString()。

应该可以的。

【讨论】:

做不到。这是第三方库对象。 如果 MyOtherClass 没有密封,那么试试这个: class MyOtherClass2 : MyOtherClass public string ToString() /*return string here which you want to appear in the grid*/ 【参考方案3】:

如果您想像这样使用许多子元素:

class MyClass

   public int Id;
   public MyOtherClass OtherClass;


class MyOtherClass

   public string Name;
   public int Number;

怎么样

第一种解决方案 在设置数据源之后手动设置某些事件中每个单元格的值(也许另一个更好),例如:

private void dgv_CellFormatting( object sender, DataGridViewCellFormattingEventArgs e )

   MyClass data = dgv.Rows[ e.RowIndex ].DataBoundItem as MyClass;

   dgv.Rows[ e.RowIndex ].Cells[ "colName" ].Value = data.OtherClass.Name;
   dgv.Rows[ e.RowIndex ].Cells[ "colNumber" ].Value = data.OtherClass.Number;

第二个解决方案 从数据中创建一个DataTable然后绑定呢?

如果有任何意见,我将不胜感激;-)

【讨论】:

【参考方案4】:

听起来 DataGridView 的虚拟模式可以解决您的问题。在虚拟模式下,DataGridView 将在需要显示单元格时触发一个事件。该事件允许您随意填充单元格。虚拟模式的优点是系统只需要提取实际显示的数据,因此在加载所有内容时不会出现缓慢的启动时间。

    private void my_init_function() 
        datagridview.VirtualMode = true;
        datagridview.CellValueNeeded += new System.Windows.Forms.DataGridViewCellValueEventHandler(datagridview_CellValueNeeded);
    

    private void datagridview_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
    
        e.Value = get_my_data(e.RowIndex, e.ColumnIndex);
    

【讨论】:

【参考方案5】:

将数据网格的特定列数据绑定到数据网格数据源的子属性的方法是使用DataGridView.Column.Tag 属性以及子对象内的ToString() 覆盖方法。如下:

public class Car

    public int Id  get; set; 

    public int Name  get; set; 

    public string Colour  get; set; 

    public Wheel Wheel  get; set; 


public class Wheel 

    public string WheelName  get; set; 

    public override string ToString()
    
        return WheelName;
    


public class Main

   private void LoadGrid(List<Car> data)
   
       this.dataGridView.Columns["Wheel"].Tag = "WheelName";
   

【讨论】:

以上是关于DataGridViewColumn.DataPropertyName 属性的主要内容,如果未能解决你的问题,请参考以下文章