Sometimes we need to load a list of items to a ComboBox or DropDownList for the user to select a value to be processed. Items are loaded in the ComboBox generally to be bound to a data source of the ComboBox. The data source is bound to a ComboBox using the "DataSource" property.
As per MSDN documentation, DataSource can be an object that implements the IList interface (such as a DataSet, DataTable, List, Array, and DataView). The default is null. When the DataSource property is set, the items collection cannot be modified.
To explain data source binding with various objects I created a demo project that demonstrates the following kind of bindings:
- Binding DataSource with Array
- Binding DataSource with List
- Binding DataSource with DataSet
- Binding DataSource with DataTable
- Binding DataSource with DataView
- Binding DataSource with Enumeration Values
For our understanding, a sample project is also attached with this article. Here is a screenshot of the main form of the project:
Binding with Array
We know that any object implementing the IList interface can be bound to a "ComboBox.DataSource". Array is one of them. Suppose we have a class "Person" with the properties: Name, Rank and Gender. Now we want to populate a ComboBox with the person's name and when the user selects a name on the list, his/her corresponding gender is displayed. Here is the related code
class Person {
public string Name {
get;
set;
}
public int Rank {
get;
set;
}
public string Gender {
get;
set;
}
public Person(int r, string n, string g) {
Rank = r;
Name = n;
Gender = g;
}
}
private void btn_FillWithArray_Click(object sender, EventArgs e) {
try {
Person[] list = new Person[] {
new Person(1, "Jon", "M"),
new Person(2, "Ram", "M"),
new Person(3, "Rin", "F"),
new Person(4, "Sue", "F"),
new Person(5, "Ken", "M"),
new Person(6, "Tom", "M"),
new Person(7, "Sam", "M")
};
comBox_FilledWithArray.DataSource = list;
comBox_FilledWithArray.DisplayMember = "Name";
comBox_FilledWithArray.ValueMember = "Gender";
} catch (Exception exc) {
MessageBox.Show(exc.Message);
}
}
private void comBox_FilledWithArray_SelectionChangeCommitted(object sender, EventArgs e) {
lbl_ArrayValue.Text = "Gender: " + comBox_FilledWithArray.SelectedValue.ToString();
}
Binding with List
A List collection in .Net also implements the IList interface so it can be bound to a ComboBox's DataSource too. Here we want to display a person's rank in the list and when the user selects a rank from the ComboBox items, the corresponding name is displayed.
private void btn_FillWithList_Click(object sender, EventArgs e) {
try {
List < Person > list = new List < Person > () {
new Person(1, "Jon", "M"),
new Person(2, "Ram", "M"),
new Person(3, "Rin", "F"),
new Person(4, "Sue", "F"),
new Person(5, "Ken", "M"),
new Person(6, "Tom", "M"),
new Person(7, "Sam", "M")
};
comBox_FilledWithList.DataSource = list;
comBox_FilledWithList.DisplayMember = "Rank";
comBox_FilledWithList.ValueMember = "Name";
} catch (Exception exc) {
MessageBox.Show(exc.Message);
}
}
private void comBox_FilledWithList_SelectionChangeCommitted(object sender, EventArgs e) {
lbl_ListValue.Text = "Name: " + comBox_FilledWithList.SelectedValue.ToString();
}
Binding with DataSet
Since DataSet implements the IList interface too, it can be bound to a ComboBox's DataSource. Now let us see how to bind a DataSet as a Data Source. Assume you get the data from a database into a DataSet using a Stored Procedure "usp_GetAllAddresses" (refer to the "GetDataFromDatabaseinDataSet()" method and the following Stored Procedure). Here we can see that the columns names are ID, LastName, FirstName and City. Out of these columns any two columns that can be chosen as DispalyMember and as ValueMember respectively while binding with DataSet.
STORED PROCEDURE
CREATE PROCEDURE [dbo].[usp_GetAllAddresses]
AS
BEGIN
SELECT [P_Id] as ID
,[LastName] as LastName
,[FirstName] as FirstName
,[Address] as Address
,[City] as City
FROM [ADDRESS]
END
CODE
private void btn_FillWithDataSet_Click(object sender, EventArgs e) {
try {
DataSet dsDataFromDB = GetDataFromDatabaseinDataSet();
comBox_FilledWithDataSet.DataSource = dsDataFromDB.Tables[0];
comBox_FilledWithDataSet.DisplayMember = "FirstName";
comBox_FilledWithDataSet.ValueMember = "City";
} catch (Exception exc) {
MessageBox.Show(exc.Message);
}
}
private void comBox_FilledWithDataSet_SelectionChangeCommitted(object sender, EventArgs e) {
lbl_DataSetValue.Text = "City Name: " + comBox_FilledWithDataSet.SelectedValue.ToString();
}
public DataSet GetDataFromDatabaseinDataSet() {
DataSet ds = new DataSet();
try {
// database Connection String
string connectionString = "Server = .; database = HKS; Integrated Security = true";
using(SqlConnection sqlCon = new System.Data.SqlClient.SqlConnection(connectionString)) {
using(SqlDataAdapter SqlDa = new SqlDataAdapter("usp_GetAllAddresses", sqlCon)) {
SqlDa.SelectCommand.CommandType = CommandType.StoredProcedure;
SqlDa.Fill(ds);
}
}
return ds;
} catch (Exception) {
throw;
}
}
Binding with DataTable
Here we are getting data from a database in a DataTable instead of a DataSet (as in the previous section) and bind it to a Combo Box.
private void btn_FillWithDataTable_Click(object sender, EventArgs e) {
try {
DataTable dtDataFromDB = GetDataFromDatabaseinDataTable();
comBox_FilledWithDataTable.DataSource = dtDataFromDB;
comBox_FilledWithDataTable.DisplayMember = "ID";
comBox_FilledWithDataTable.ValueMember = "FirstName";
} catch (Exception exc) {
MessageBox.Show(exc.Message);
}
}
private void comBox_FilledWithDataTable_SelectionChangeCommitted(object sender, EventArgs e) {
lbl_DataTableValue.Text = "First Name: " + comBox_FilledWithDataTable.SelectedValue.ToString();
}
public DataTable GetDataFromDatabaseinDataTable() {
DataTable dt = new DataTable();
try {
// database Connection String
string connectionString = "Server = .; database = HKS; Integrated Security = true";
using(SqlConnection sqlCon = new System.Data.SqlClient.SqlConnection(connectionString)) {
using(SqlDataAdapter SqlDa = new SqlDataAdapter("usp_GetAllAddresses", sqlCon)) {
SqlDa.SelectCommand.CommandType = CommandType.StoredProcedure;
SqlDa.Fill(dt);
}
}
return dt;
} catch (Exception) {
throw;
}
}
Binding with DataView
DataView in .Net also implements the IList interface, so it can be bound to a ComboBox's DataSource too. DataView is generally used to get a collection in a desired view after filtering out some rows from a DataTable. In the following code, we got the data from the database in a DataTable and after that we filtered out some rows ( ID > 5 ) and saved the required filtered data into a DataView.
private void btn_FillWithDataView_Click(object sender, EventArgs e) {
try {
DataTable dtDataFromDB = GetDataFromDatabaseinDataTable();
// Filtering rows with DataView class
DataView dv = new DataView(dtDataFromDB);
dv.RowFilter = "ID < 5";
comBox_FilledWithDataView.DataSource = dv;
comBox_FilledWithDataView.DisplayMember = "ID";
comBox_FilledWithDataView.ValueMember = "FirstName";
} catch (Exception exc) {
MessageBox.Show(exc.Message);
}
}
private void comBox_FilledWithDataView_SelectionChangeCommitted(object sender, EventArgs e) {
lbl_DataViewValue.Text = "First Name: " + comBox_FilledWithDataView.SelectedValue.ToString();
}
Binding with Enumeration
We could bind any ComboBox to a list of an enumeration values easily by using its GetValues() method. Actually the GetValues() method of Enum returns an array of objects (as we know, that implements the IList interface). We can use this method to convert an enum to an array and bind to a ComboBox.
enum Weekdays {
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
};
private void btn_FillWithEnumeration_Click(object sender, EventArgs e) {
comBox_FilledWithEnumeration.DataSource = Enum.GetValues(typeof(Weekdays));
}
private void comBox_FilledWithEnumeration_SelectionChangeCommitted(object sender, EventArgs e) {
lbl_EnumerationValue.Text = "Selected day is: " + comBox_FilledWithEnumeration.SelectedValue.ToString();
}
Summary
So here we learned how to bind a ComboBox DataSource to any Array of objects, List of Objects, DataTable, DataSet, DataView and Enumeration Values.