Click here to Skip to main content
15,891,409 members
Articles / Programming Languages / C#
Article

A ComboBox in a DataGrid

Rate me:
Please Sign up or sign in to vote.
4.00/5 (59 votes)
25 Dec 20021 min read 439.5K   2.2K   75   79
Descendant from DataGridColumnStyle.

Introduction

This is a descendant from DataGridColumnStyle and is used to have a ComboBox in a DataGrid column. It is based on an article by Sudhakar Jalli but I found the code not working. I repaired the code and cleaned it up a little.

The DataGridComboBoxColumn class makes it possible to have a ComboBox instead of the default text or checkbox. It took me quite a while to figure it out (even with the help of the article by Sudhakar Jalli). Using it is straightforward.

Using the code

First create a new DataGridTableStyle and make sure the mapping is set to the name of the table in the DataSource where the columns will belong to.

C#
DataGridTableStyle ts=new DataGridTableStyle();
ts.MappingName="Columns";

Then, create the DataTable with the lookup values. This could of course come from the database (And it should BTW)

C#
DataTable AccessDataTypes = new DataTable();
AccessDataTypes.Columns.Add(new DataColumn("Number", typeof(int)));
AccessDataTypes.Columns.Add(new DataColumn("Name", typeof(string)));
AccessDataTypes.Rows.Add(new object[] {3, "Numeric"});
AccessDataTypes.Rows.Add(new object[] {130, "Text"});

Create the DataGridComboBoxColumn and add it to the GridColumnStyles. The first argument (Type) is used for the column caption and the mapping. (Could be changed after creating). The second argument (AccessDataTypes) is the DataTable to use for translation. Name and Number are the column names to use from the table and theGrid is the DataGrid where this column will belong to. Be sure to provide the NullText ; if you don't it will throw an exception if you try to add a row to the DataGrid.

C#
DataGridComboBoxColumn c1=new DataGridComboBoxColumn("Type", 
         AccessDataTypes, "Name", "Number", theGrid);
c1.NullText="3";
ts.GridColumnStyles.Add(c1);

Finally add the newly created TableStyle to the TableStyles array of the DataGrid.

C#
theGrid.TableStyles.Add(ts);

Enjoy the improved DataGrid and be sure to send in your own DataGrid columns!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Netherlands Netherlands
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionReadOnly property? Pin
Member 100790095-Nov-03 9:06
Member 100790095-Nov-03 9:06 
GeneralFormatException raised... Pin
leplayb5-Sep-03 0:21
leplayb5-Sep-03 0:21 
GeneralRe: FormatException raised... Pin
JoeGunchy11-Sep-03 12:05
JoeGunchy11-Sep-03 12:05 
GeneralRe: FormatException raised... Pin
12-Sep-03 7:53
suss12-Sep-03 7:53 
GeneralRe: FormatException raised... Pin
JoeGunchy16-Sep-03 14:27
JoeGunchy16-Sep-03 14:27 
GeneralRe: FormatException raised... Pin
bart_dv7-Jul-04 0:42
bart_dv7-Jul-04 0:42 
GeneralEditable ComboBox Pin
JoeGunchy26-Aug-03 10:32
JoeGunchy26-Aug-03 10:32 
GeneralRe: Editable ComboBox Pin
JoeGunchy11-Sep-03 12:23
JoeGunchy11-Sep-03 12:23 
I added a few more changes:

1)
Edit():
Change:
_comboBox.SelectedValue = GetText(GetColumnValueAtRow(source, rowNum));
To:
// Added this if statement to handle an error when the text field was null
if( (GetText(GetColumnValueAtRow(source, rowNum)) != "") && ((GetText(GetColumnValueAtRow(source, rowNum)) != null)) )
{
_comboBox.SelectedValue = GetText(GetColumnValueAtRow(source, rowNum));
}

2)
The .Visible will force the comboBox to be selected at Index 0, but will not display that value. When the user clicks off of the cell (without selecting a dropdown value) the Comit method will save whatever was selected, which would always be whatever was at Index 0. So, we force the Index back to -1, unselected.

After this line: _comboBox.Visible = true;
Add: _comboBox.SelectedIndex=-1;

I also had probs in the Comit() method. Problem was that if you clicked anywhere in the grid the combobox would trigger and whatever value was at index zero of the comboBox would auto-populate the cell. Also if the user did not enter any data the combobox would write a null to the dataSet and trigger the .HasChanges flag. So now this method checks before hand and if the cell in the dataSet is the same as the attepmted save the save will abort.

But now there is no way a user can enter a null, so a null must be included in the drop-down.

Here is the entire method:
///
/// Standard override
///

/// <param name="dataSource" />
/// <param name="rowNum" />
/// <returns>
protected override bool Commit(CurrencyManager dataSource,int rowNum)
{
//if(!_inEdit)
//{
// return true;
//}
// BugFix: Replaced the above if with the if below.
// We had the problem that the combobox would alter the DataSet when in fact it should not.
// This will not abort when the user has not typed anything and the Selected index is -1 (which we set from a proir bugfix)

if(((_comboBox.SelectedIndex==-1)&&(_comboBox.Text=="")) || !_inEdit)
{
Abort(rowNum);
return true;
}
try
{
//object _value = _comboBox.SelectedValue;
object _value = _comboBox.Text;
if(NullText.Equals(_value))
{
_value = System.Convert.DBNull;
}
// Added the if below which will not write a null if the data in the field is the same
// This will avoid setting the .hasChanges flag.
if(this.GetColumnValueAtRow(dataSource, rowNum)!=_value)
this.SetColumnValueAtRow(dataSource, rowNum, _value);
}
catch
{
// This catch will catch when a user enters the wrong data type.
// We store a null value then return true
this.SetColumnValueAtRow(dataSource, rowNum, System.DBNull.Value);
return true;
//return false;
}
finally
{
_inEdit=false;
_comboBox.Hide();
}
return true;
}

The commented out code was code from the original author.
I hope this helps someone.
GeneralRe: Editable ComboBox Pin
robgale2-May-04 18:17
robgale2-May-04 18:17 
GeneralDatagrid Cell Formatting Pin
meatcp6-Aug-03 20:25
meatcp6-Aug-03 20:25 
GeneralNullText property Pin
DancnDude9-Jul-03 6:40
DancnDude9-Jul-03 6:40 
GeneralRe: NullText property Pin
Chris Wuestefeld23-Nov-03 13:52
Chris Wuestefeld23-Nov-03 13:52 
Generalkeybord access Pin
wengerp27-May-03 10:04
wengerp27-May-03 10:04 
GeneralRe: keybord access Pin
Roger Willcocks16-Sep-03 15:11
Roger Willcocks16-Sep-03 15:11 
Generalsetting the alternating background coloe Pin
merojo8-May-03 12:15
merojo8-May-03 12:15 
GeneralTo the author!!! Pin
Member 6049431-Mar-03 17:57
Member 6049431-Mar-03 17:57 
GeneralRe: To the author!!! Pin
torok9-Apr-03 13:36
torok9-Apr-03 13:36 
GeneralRe: To the author!!! Pin
bill_cs3-Aug-07 4:37
bill_cs3-Aug-07 4:37 
GeneralRestricted to list Pin
torok20-Mar-03 8:55
torok20-Mar-03 8:55 
GeneralConverting to Visual Basic.Net Pin
John Thayer17-Mar-03 6:13
John Thayer17-Mar-03 6:13 
GeneralRe: Converting to Visual Basic.Net Pin
Jan Wiggers17-Mar-03 19:15
Jan Wiggers17-Mar-03 19:15 
GeneralRe: Converting to Visual Basic.Net Pin
John Thayer18-Mar-03 4:40
John Thayer18-Mar-03 4:40 
GeneralRe: Converting to Visual Basic.Net Pin
sracer620-Jan-06 13:14
sracer620-Jan-06 13:14 
GeneralDataGridColumnStyle is abstract Pin
JBs10-Jan-03 2:29
JBs10-Jan-03 2:29 
GeneralRe: DataGridColumnStyle is abstract Pin
Jan Wiggers10-Jan-03 9:09
Jan Wiggers10-Jan-03 9:09 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.