JohnG
JohnG

Reputation: 9469

DataGridView with data source reports two different CurrentCellAddress row values

I have a DataGridView with a DataTable as a DataSource, a Label that displays the currently selected cells address in the DataGridView and finally there is a Button that button opens a MessageBox to display the same currently selected cell address.

The label’s text is update in the DataGridViews CellClick event.

Using the picture below as an example: When the last “NewRow” is selected, the label will be updated correctly with the correct row five (5) index. However, when I click on the button and display the same selected cell address, the row index is four (4).

I am guessing this is has something to do with the DataSource/DataTable since this does NOT happen if the DataGridView is NOT bound to a data source.

enter image description here

I have a workaround for this, however I am not understanding why the same method dataGridView1.CurrentCellAddress appears to be returning incorrect/different values. What is going on from the time the method CurrentCellAddress is called in the cell click event and the same method is called later when the button is clicked? The selection has NOT changed yet it appears they are different numbers. Thanks for any help.

Code I am using to test this…

DataTable gridData;

public Form1() {
  InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e) {
  //FillGrid();
  gridData = GetTable();
  FillDT(gridData);
  dataGridView1.DataSource = gridData;
  label1.Text = "CurrentCellAddress: " + dataGridView1.CurrentCellAddress.ToString();
}

private DataTable GetTable() {
  DataTable dt = new DataTable();
  dt.Columns.Add("Col1", typeof(String));
  dt.Columns.Add("Col2", typeof(String));
  dt.Columns.Add("Col3", typeof(String));
  return dt;
}

private void FillDT(DataTable dt) {
  for (int i = 0; i < 5; i++) {
    dt.Rows.Add("R" + i + "C1", "R" + i + "C2", "R" + i + "C3");
  }
}

private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e) {
  label1.Text = "CurrentCellAddress: " + dataGridView1.CurrentCellAddress.ToString();
}

private void btnGetCellAddress_Click(object sender, EventArgs e) {
  MessageBox.Show("CurrentCellAddress: " + dataGridView1.CurrentCellAddress.ToString(),"Cell Address");
}

// Method to fill the grid to show the values are correct 
// when the datagridview is not data bound
private void FillGrid() {
  dataGridView1.Columns.Add(new DataGridViewTextBoxColumn());
  dataGridView1.Columns.Add(new DataGridViewTextBoxColumn());
  dataGridView1.Columns.Add(new DataGridViewTextBoxColumn());
  for (int i = 0; i < 5; i++) {
    dataGridView1.Rows.Add("R" + i + "C1", "R" + i + "C2", "R" + i + "C3");
  }
}

Upvotes: 0

Views: 313

Answers (1)

Chawin
Chawin

Reputation: 1466

When focus of the DataGridView control is lost the OnValidating method (source reference) is eventually called, which contains the following code:

// Current cell needs to be moved to the row just above the 'new row' if possible.
int rowIndex = this.Rows.GetPreviousRow(this.ptCurrentCell.Y, DataGridViewElementStates.Visible);

Selecting cells within the DataGridView keeps focus on the control, so this is never called. However, when using the button the focus is lost and OnValidating will move the current cell one row above the empty new row.

Upvotes: 1

Related Questions