Wed Dec 07 2005
**sigh **Winforms team, winforms team, when will you start making my life easier? As others have said (and I completely agree) windowsforms.net is pretty useless. Well, there's some new Whidbey .NET 2.0 content, but all of the things I enjoyed when starting w/ v1 of .NET (like, erm, QuickStarts? What happened to installing those locally?) seem to be gone. To be fair, they do have a presence over on forums.microsoft.com where there are a few PM's and devs answering questions. I even found a hack fix for my dilemma via one of the posts that links to a download from Beta 2 or somewhere close.
At first I was optimistic about the DataGridView samples (overview)(Download The DataGridView samples), but I didn't see anything that did what I wanted to do: take an enum value and represent it in the grid with a combobox. So, here's how I did it.
First, I just plopped a DataGridView onto a form and gave it a BindingSource. The bindingSource gets its DataSource property set via a call into my DAL that returns a DataTable:
//CF: set to null before setting it to the current to
//clear out previous results
this.bindingSource1.DataSource = null;
this.bindingSource1.DataSource = MyDal.GetDataTable();Then comes the hackery. Since I have about 20 columns in this DataTable, all of interest as far as values but not all needing to be visible, directly after (like the line after) setting the datasource, I call a method to format the grid. This method looks something like this:
private void _formatGrid(){
this.dataGridView1.Columns["ID"].Visible = false;
this.dataGridView1.Columns.Remove("Status");//CF: this is where we want enums.
...
this._formatStatusColumn();
}Then the _formatStatusColumn method is where the magick happens:
DataTable dt = new DataTable("Status");
//CF: actually how it's stored in the db.
dt.Columns.Add("Status", typeof(int));
dt.Columns.Add("Status_Name", typeof(string));
//CF: this way I can add or remove enum values, and
//the combo will always reflect the correct values.
foreach(int index in Enum.GetValues(typeof(Status)){
dt.Rows.Add(index, Enum.GetName(typeof(Status), index));
}
//CF: now for the UI column
DataGridViewComboBoxColumn statusColumn =
new DataGridViewComboBoxColumn();
//CF: seems to control where the column is placed.
statusColumn.DisplayIndex = 3;
statusColumn.HeaderText = "Status";
statusColumn.DataPropertyName = "Status";
statusColumn.DataSource = dt;
statusColumn.DisplayMember = "Status_Name";
statusColumn.ValueMember = "Status";
this.dataGridView1.Columns.Add(statusColumn);I was hoping that there would be some way to predefine columns so I don't have to filter and rebuild every time I get data from the database, but I couldn't find anything on it. There is no SelectedIndex member of the DataGridViewComboBoxCell, either.
I really hope this helps someone else out there: I tried for a day and a half to get this to work, and I still think it looks like a hack.