Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A Data Bound Combo Box

0.00/5 (No votes)
5 Dec 2004 1  
This article provides a combo box that is easy to use with data sources.

Sample Image - DataComboBox.png

Introduction

So why did I make this control? Lots of software development companies produce software for small businesses, and lots of these products are called ERPs. These applications use as many databases as possible, believe me, I know an ERP project that uses such a control in almost every form, and it has two hundred to three hundred forms. Why use this? Because it allows you to bind a data source to a combo box, bind in the meaning that if the data source changes, the control items change too. And when an item is selected, a data row can be obtained from that item, and finally the data row's primary keys.

About the Control

Except what I mentioned before, this control has an item format property, which is used to format the items based on the data row.

Let's say we have a table with lots of stuff, with an employee name, age, and salary... We want to show in the control its items in the following way: "Elvis Preasy, income 200$". The row format does this thing by passing to it the column indexes surrounded by <> (like HTML tags). So in the previous example, the format string would be "<1> <2>, income <3>$", assuming that column 1 and 2 define the employee name and column 3 his income.

And this is not all, the control supports row filtering, actually it doesn't filter its items, it recreates new ones based on the filter. The filter is like the ADO.NET data view row filter.

The last drop is made by the possibility to get the row corresponding to an item (the selected item), and its primary keys.

How All This Is Made?

All this is made by holding into the control the data source (some want to know what is the data source), the corresponding table that gives us the items, a data view for the filtering, and some entities used for the data rows association (means that a row has an item attached to it).

// the association between all items and data rows
private ArrayList _bindedItems = new ArrayList();
// a data source object, not really used, but i needed 
private object _dataSource = null;
// the inner table that contains all the data binded to the control
private DataTable _controlDataTable = null;
// the inner data view that filters the inner table
private DataView _dataView = new DataView();
// a data member functionality
private string _dataMember = "";
// the display format for the items
private string _displayFormat = "";
// a row filter for the items
private string _rowFilter = "";

All the operations are made at the calls to the control properties:

// format template : "some text <column number> some text <column number> ..."
public string BindedDataFormat [...]
// like ADO.NET data view row filter
public string BindedDataFiler [...]
public object BindedDataSource [...]
public string BindedDataMember [...] 
// get or set the selected item's data row
public DataRow SelectedRow [...]

There are some inner private functions that process all the data and a static procedure that returns the primary keys of a data row in an object vector:

public static object[] GetRowPK(DataRow row) 
{
    ArrayList pks = new ArrayList(); // make a new array list to hold the result
    DataTable dt = row.Table;        // get the data table associated with the row
    // and foreach data column witch is a primary key
    foreach(DataColumn dc in dt.PrimaryKey) 
    {
        pks.Add(row[dc]);            // add in the list its content
    }
    return pks.ToArray();            // finally return a object array
}

The DropDownStyle property of the control is read only to avoid ambiguity, and a lots of headaches.

To make this control bind to the data source, I added the data table that gives all the rows we need, a handling procedure at row changed and row deleted. At a data source change, the old table's handling methods are removed.

// used to dynamically modify the control's items in case the data source changes 
private DataRowChangeEventHandler _rowChanged;
private void SetControlData()
{ 
   if(_controlDataTable == null) 
       return; 
   _controlDataTable.RowChanged += _rowChanged; 
   _controlDataTable.RowDeleted += _rowChanged;
private void ClearControlData() 
{ 
   if(_controlDataTable != null) 
   { 
       _controlDataTable.RowChanged -= _rowChanged; 
       _controlDataTable.RowDeleted -= _rowChanged; 
   }

In a form, it is very easy to use the control..., just attach a format on it (or it will not display anything) and set its data source:

comboBox1.BindedDataFormat = "<id> <0>, <name> <1>, <surname> <2> ";
comboBox1.BindedDataSource = dataTable;

Instead of Ending

I hope somebody finds this control useful, for I already found it...

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