Reputation: 8035
I have a DataGridView
with several created columns. I've add some rows and they get displayed correctly; however, when I click on a cell, the content disappears.
What am I doing wrong?
The code is as follows:
foreach (SaleItem item in this.Invoice.SaleItems)
{
DataGridViewRow row = new DataGridViewRow();
gridViewParts.Rows.Add(row);
DataGridViewCell cellQuantity = new DataGridViewTextBoxCell();
cellQuantity.Value = item.Quantity;
row.Cells["colQuantity"] = cellQuantity;
DataGridViewCell cellDescription = new DataGridViewTextBoxCell();
cellDescription.Value = item.Part.Description;
row.Cells["colDescription"] = cellDescription;
DataGridViewCell cellCost = new DataGridViewTextBoxCell();
cellCost.Value = item.Price;
row.Cells["colUnitCost1"] = cellCost;
DataGridViewCell cellTotal = new DataGridViewTextBoxCell();
cellTotal.Value = item.Quantity * item.Price;
row.Cells["colTotal"] = cellTotal;
DataGridViewCell cellPartNumber = new DataGridViewTextBoxCell();
cellPartNumber.Value = item.Part.Number;
row.Cells["colPartNumber"] = cellPartNumber;
}
Thanks!
Upvotes: 8
Views: 74272
Reputation: 11576
Just to extend this question, there's also another way to add a row to a DataGridView
, especially if the columns are always the same:
object[] buffer = new object[5];
List<DataGridViewRow> rows = new List<DataGridViewRow>();
foreach (SaleItem item in this.Invoice.SaleItems)
{
buffer[0] = item.Quantity;
buffer[1] = item.Part.Description;
buffer[2] = item.Price;
buffer[3] = item.Quantity * item.Price;
buffer[4] = item.Part.Number;
rows.Add(new DataGridViewRow());
rows[rows.Count - 1].CreateCells(gridViewParts, buffer);
}
gridViewParts.Rows.AddRange(rows.ToArray());
Or if you like ParamArrays:
List<DataGridViewRow> rows = new List<DataGridViewRow>();
foreach (SaleItem item in this.Invoice.SaleItems)
{
rows.Add(new DataGridViewRow());
rows[rows.Count - 1].CreateCells(gridViewParts,
item.Quantity,
item.Part.Description,
item.Price,
item.Quantity * item.Price,
item.Part.Number
);
}
gridViewParts.Rows.AddRange(rows.ToArray());
The values in the buffer need to be in the same order as the columns (including hidden ones) obviously.
This is the fastest way I found to get data into a DataGridView
without binding the grid against a DataSource
. Binding the grid will actually speed it up by a significant amount of time, and if you have more then 500 rows in a grid, I strongly recommend to bind it instead of filling it by hand.
Binding does also come with the bonus that you can keep the Object in tact, f.e. if you want to operate on the selected row, you can do this is the DatagridView is bound:
if(gridViewParts.CurrentRow != null)
{
SaleItem item = (SalteItem)(gridViewParts.CurrentRow.DataBoundItem);
// You can use item here without problems.
}
It is advised that your classes which get bound do implement the System.ComponentModel.INotifyPropertyChanged
interface, which allows it to tell the grid about changes.
Upvotes: 7
Reputation:
Edit: oops! made a mistake on the second line of code. - fixed it.
Sometimes, I hate defining the datasource property.
I think that whenever you create and set a new row for "row", for some weird reason,the old value get disposed. try not using an instance to hold the rows you create :
int i;
i = gridViewParts.Rows.Add( new DataGridViewRow());
DataGridViewCell cellQuantity = new DataGridViewTextBoxCell();
cellQuantity.Value = item.Quantity;
gridViewParts.Rows[i].Cells["colQuantity"] = cellQuantity;
It seems like cells work fine with the cell instances. I have no idea why it is different for rows though. More testings may be required...
Upvotes: 4