DataGridView Event to Catch When Cell Value Has Been Changed by User

CellValueChanged is what you need:

private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e){
  if(dataGridView1.Columns[e.ColumnIndex].Name == "Reference"){
    //your code goes here
  }
}

I think the event CellEndEdit is also suitable for your want:

private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e){
  if(dataGridView1.Columns[e.ColumnIndex].Name == "Reference"){
    //your code goes here
  }
}

In my case CellValueChanged event was also triggering while the DGV was initializing, so I wanted to use CellEndEdit, as King King mentioned in his answer.

To make King King's second answer more bullet-proof (see JPProgrammer's comment), i.e. only react, if a value was entered in the cell, you can do the following:

   private void DataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
   {
        int? rowIdx = e?.RowIndex;
        int? colIdx = e?.ColumnIndex;
        if (rowIdx.HasValue && colIdx.HasValue)
        {
            var dgv = (DataGridView)sender;
            var cell = dgv?.Rows?[rowIdx.Value]?.Cells?[colIdx.Value]?.Value;
            if (!string.IsNullOrEmpty(cell?.ToString()))
            {
                // your code goes here
            };
        };
   }

Notice the null handling by using ?. and ?[ operators. I have written it so that it can be used in a more general way, but of course you can add the check for the "Reference" column, just replace the inner if statement above by the following:

       if (dgv.Columns[colIdx.Value].Name == "Reference")
       {
          if (!string.IsNullOrEmpty(cell?.ToString()))
          {
               // your code goes here
          };
       };