views:

675

answers:

4

When manipulating DataGridView cells, you typically do:

MyGrid.CurrentRow.Cells["EmployeeFirstName"].Value = "John";

which is all fine and dandy, but as complexity rises, you start worrying about spelling errors, refactoring issues etc.

Historically, I just made the columns public so I could access them directly in the class instance, but I then have to fight the Windows Forms designer which wants to keep them private (supposedly because it's good practice).

My current solution is to have a class called Cols, with a bunch of strings:

public static class Cols
{
    public static string EmployeeFirstName = "EmployeeFirstName";
    ...
}

Which results in this:

MyGrid.CurrentRow.Cells[Cols.EmployeeFirstName].Value = "John";

This gives me some IntelliSense goodness as opposed to waiting for a runtime error. It still seems vaguely hack-ish, though.

Is there an even more convenient way to do this?

A: 

You can use index to access your columns as:

MyGrid.CurrentRow.Cells[1].Value = "John";

Bhaskar
How is this save? if the column index changes, you're screwed...
Colin
A: 

If you've created your columns at design-time, you can give them sensible names such as employeeFirstNameColumn.

Then you can get to a cell using something like:

MyGrid.CurrentRow.Columns[employeeFirstNameColumn.Name]

or maybe:

MyGrid.CurrentRow.Columns[employeeFirstNameColumn.Index]

If you're generating the columns dynamically (AutoGenerateColumns = true), you'll have column indices based on the column indices of the datasource you're binding too. So you may be able to use a similar trick to derive the index (especially if your datasource is a strongly-typed DataSet).

Joe
I've been reading up a bit, and it seems I'm trying to have it both ways by both wanting to adhere to the "all members are private" behavior of the Windows Forms Designer, but still wanting full access to the class instance where I actually use the form.It's take it or leave it, I guess. Thanks for your ideas, though.
Teetow
A: 

The only way to prevent run-time problems is to catch the ArgumentException when trying to access a non-existent Cells item. For example:

private void SetCellValue(DataGridViewCellCollection cells, string col, object value)
{
  try
  {
    cells[col].Value = value;
  } 
  catch (Exception ex)
  {
    Console.WriteLine(string.Format("Failed to set cell {0} to {1} Error={2}",col,value,ex.Message));
  }
}
Bob Nadler
A: 

What you can do is this

for (int x = 0;x <tbl.Rows.Count;x++)//iterate through tables
         {
          Dataset.TableNameRow record = tbl[x];
            dataGridView1.Rows.Add();
            dataGridView1[colHandoffDate.Name,x].Value = record.HandoffDate;
          ....

I added the columns manually , so you could find them in intellisense and use their names(this way you don't have to create a class with strings)

DanSmith