Property DataGridViewColumn.DataPropertyName

I have a DataGridView control and I want to populate it with data.

I am using the DataSource property

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

Now problem number one. The class in my collection does not contain only simple types that I can map to columns using DataPropertyName. This is the class that is contained in the collection.

 class MyClass { public String Name; MyOtherClass otherclass; } class MyOtherClass { public String Name; } 

Now I bind MyClass properties to columns

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

The problem is that I want to display the otherclass.Name field. But if I try to write

 col2.DataPropertyName = "otherclass.Name" 

I get an empty cell.

I tried to manually set the column

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

But this foreach loop takes about a minute to complete (2k items). How to solve this problem?

+7
winforms datasource datagridview
source share
5 answers

DataGridView does not support data binding to child properties. Check this post for more information.

I like the solution using the CellFormatting event.

+3
source share

If you want to use many children, for example:

 class MyClass { public int Id; public MyOtherClass OtherClass; } class MyOtherClass { public string Name; public int Number; } 

What about

1st solution Set a value for each cell in an event (another one is better), manually, after setting the data source, for example:

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

2nd solution How about creating a DataTable from the data and then link it?

I would be grateful for any opinion; -)

+3
source share

Problem number 1:

Try the following:

  • extends MyOtherClass from Object (this step may not be necessary)

  • and override or create the ToString () method.

That should do it.

+2
source share

It seems that the virtual mode of the DataGridView will solve your problem. In virtual mode, the DataGridView fires an event when it needs to display a cell. The event allows you to fill in the cell as you like. The advantage of virtual mode is that the system only needs to pull out the data that is actually displayed, so there is no slow startup time when loading everything.

  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); } 
+1
source share

The way to bind data to a specific datagrid column to a child property of a datagrid data source uses the DataGridView.Column.Tag property, as well as the ToString() override method inside the child object. This happens as follows:

 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"; } } 
+1
source share

All Articles