Like the OnCellToolTipTextNeeded(...)
and OnRowErrorTextNeeded(...);
built-in methods, there should have been an OnRowHeaderCellValueNeeded(...);
method but there isn't one.
There are two protected methods OnRowErrorTextNeeded(...)
or OnRowPrePaint(...)
that look promising, however there are side-effects trying to use them, i.e. "rowIndex out of bounds". Also, if DoubleBuffered
is false then the result is the process crashes.
The method that seems to behave without side-effects is the OnCellErrorTextNeeded(...)
method. Looking at the stack trace, that method is called inside of a private PaintWork(...)
method, whereas the OnRowErrorTextNeeded(...)
method is not.
Also, one requirement seems to be that the row header cell value must be a String
object, or it is not drawn.
public class MyDGV : DataGridView {
// only set the HeaderCell.Value if the row is different than before
private int onCellErrorTextNeededRowIndexPrevious = -1;
public MyDGV() {
this.Dock = DockStyle.Fill;
this.AllowUserToAddRows = false;
this.AllowUserToResizeRows = false;
this.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells;
this.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None;
this.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.AutoSizeToDisplayedHeaders;
this.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
this.DoubleBuffered = true;
DataTable dt = new DataTable();
dt.Columns.Add("A");
dt.Columns.Add("B", typeof(DateTime));
dt.Columns.Add("C", typeof(int));
int x = 1;
DateTime date = DateTime.Today.AddDays(-52);
for (char c = 'A'; c <= 'Z'; c++) {
dt.Rows.Add(c.ToString().ToLower(), date, x++);
dt.Rows.Add(c.ToString(), date, x++);
date = date.AddDays(1);
}
this.DataSource = dt;
}
protected override void OnCellErrorTextNeeded(DataGridViewCellErrorTextNeededEventArgs e) {
base.OnCellErrorTextNeeded(e);
e.ErrorText = "Cell(" + e.ColumnIndex + ", " + e.RowIndex + ")";
if (e.RowIndex != onCellErrorTextNeededRowIndexPrevious) {
onCellErrorTextNeededRowIndexPrevious = e.RowIndex;
DataGridViewRow rs = this.Rows[e.RowIndex]; // HeaderCell requires unshared row
rs.HeaderCell.Value = (e.RowIndex + 1).ToString();
//Debug.WriteLine("getting: " + e.ErrorText); // testing only
}
else {
//Debug.WriteLine("skipping"); // testing only
}
}
protected override void OnRowErrorTextNeeded(DataGridViewRowErrorTextNeededEventArgs e) {
base.OnRowErrorTextNeeded(e);
e.ErrorText = "Cell(-1, " + e.RowIndex + ")";
}
}