Example E3689
Visible to All Users

Grid View for ASP.NET Web Forms - Cascading Combo Boxes

This example demonstrates how to implement cascading combo box editors within ASPxGridView.

CascadingComboBoxes

Setup the Grid and its Column Editors

Create an ASPxGridView control, assign its data source, and set the grid's edit mode to Inline. Add two columns of the GridViewDataComboBoxColumn type and specify their data sources.

XML
<dx:ASPxGridView ID="Grid" runat="server" AutoGenerateColumns="false" DataSourceID="Customers" KeyFieldName="CustomerID" ClientInstanceName="grid"> <Columns> <%--...--%> <dx:GridViewDataComboBoxColumn Caption="Country" FieldName="CountryID"> <PropertiesComboBox DataSourceID="Countries" ValueField="CountryID" ValueType="System.Int32" <%--...--%> </PropertiesComboBox> </dx:GridViewDataComboBoxColumn> <dx:GridViewDataComboBoxColumn Caption="City" FieldName="CityID"> <PropertiesComboBox DataSourceID="AllCities" ValueField="CityID" ValueType="System.Int32" <%--...--%> </PropertiesComboBox> </dx:GridViewDataComboBoxColumn> </Columns> <SettingsEditing Mode="Inline" /> </dx:ASPxGridView> <asp:ObjectDataSource ID="Customers" runat="server" ... /> <asp:ObjectDataSource ID="Countries" runat="server" ... /> <asp:ObjectDataSource ID="AllCities" runat="server" ... />

Respond to a Selection Change on the Client Side

Handle the primary editor's client-side SelectedIndexChanged event. In this event handler, get the editor value (the GetValue method) and pass it as a parameter in the PerformCallback method of the secondary editor. To access the secondary editor, call the GetEditor method.

XML
<dx:ASPxGridView ID="Grid" runat="server" ... > <Columns> <%--...--%> <dx:GridViewDataComboBoxColumn Caption="Country" FieldName="CountryID" ...> <PropertiesComboBox DataSourceID="Countries" ValueField="CountryID" ...> <ClientSideEvents SelectedIndexChanged="CountriesCombo_SelectedIndexChanged" /> </PropertiesComboBox> </dx:GridViewDataComboBoxColumn> <dx:GridViewDataComboBoxColumn Caption="City" FieldName="CityID" ... /> </Columns> </dx.ASPxGridView>
JavaScript
function CountriesCombo_SelectedIndexChanged(s, e) { grid.GetEditor("CityID").PerformCallback(s.GetValue()); }

Filter the Secondary Combo Box Values on the Server Side

In the CellEditorInitialize event handler, access the secondary editor and add a handler to its Callback event. In the handler, use the Parameter argument property to obtain the primary editor's value from the client side. Filter the secondary editor's data source based on this value and bind the filtered values to the editor.

C#
protected void Grid_CellEditorInitialize(object sender, ASPxGridViewEditorEventArgs e) { if(e.Column.FieldName == "CityID") { var combo = (ASPxComboBox)e.Editor; combo.Callback += new CallbackEventHandlerBase(combo_Callback); var grid = e.Column.Grid; if (!combo.IsCallback) { var countryID = -1; if (!grid.IsNewRowEditing) countryID = (int)grid.GetRowValues(e.VisibleIndex, "CountryID"); FillCitiesComboBox(combo, countryID); } } } private void combo_Callback(object sender, CallbackEventArgsBase e) { var countryID = -1; Int32.TryParse(e.Parameter, out countryID); FillCitiesComboBox(sender as ASPxComboBox, countryID); } protected void FillCitiesComboBox(ASPxComboBox combo, int countryID) { combo.DataSourceID = "Cities"; Cities.SelectParameters["CountryID"].DefaultValue = countryID.ToString(); combo.DataBindItems(); combo.Items.Insert(0, new ListEditItem("", null)); // Null Item }

Documentation

Files to Look At

More Examples

Example Code

WebSite/App_Code/DataProvider.cs(vb)
C#
using System.Collections; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.SessionState; public static class DataProvider { static HttpSessionState Session { get { return HttpContext.Current.Session; } } static DemoDataObject DemoData { get { const string key = "FB1EB35F-86F5-4FFE-BB23-CBAAF1514C49"; if (Session[key] == null) { var obj = new DemoDataObject(); obj.FillObj(); Session[key] = obj; } return (DemoDataObject)Session[key]; } } public static IEnumerable GetCustomers() { return DemoData.Customers; } public static void InsertCustomer(string customerName, int countryID, int cityID) { var c = new Customer() { CustomerID = DemoData.Customers.Count, CustomerName = customerName, CountryID = countryID, CityID = cityID }; DemoData.Customers.Add(c); } public static void UpdateCustomer(int customerID, string customerName, int countryID, int cityID) { var c = DemoData.Customers.First(i => i.CustomerID == customerID); c.CustomerName = customerName; c.CountryID = countryID; c.CityID = cityID; } public static IEnumerable GetCountries() { return DemoData.Countries; } public static IEnumerable GetCities() { return DemoData.Cities; } public static IEnumerable GetCities(int countryID) { return from c in DemoData.Cities where c.CountryID == countryID select c; } } public class DemoDataObject { public List<Customer> Customers { get; set; } public List<Country> Countries { get; set; } public List<City> Cities { get; set; } public void FillObj() { Customers = new List<Customer>(); Countries = new List<Country>(); Cities = new List<City>(); var uk = CreateCountry("UK"); var usa = CreateCountry("USA"); CreateCustomer("Jacob", CreateCity("Brighton", uk.CountryID)); CreateCustomer("Michael", CreateCity("Glasgow", uk.CountryID)); CreateCustomer("Emily", CreateCity("London", uk.CountryID)); CreateCustomer("Joshua", CreateCity("Bath", uk.CountryID)); CreateCustomer("Emma", CreateCity("Manchester", uk.CountryID)); CreateCustomer("Madison", CreateCity("Wells", uk.CountryID)); CreateCustomer("Matthew", CreateCity("York", uk.CountryID)); CreateCustomer("Olivia", CreateCity("Dallas", usa.CountryID)); CreateCustomer("Ethan", CreateCity("Las Vegas", usa.CountryID)); CreateCustomer("Hannah", CreateCity("Los Angeles", usa.CountryID)); CreateCustomer("Abigail", CreateCity("New York City", usa.CountryID)); CreateCustomer("Isabella", CreateCity("San Francisco", usa.CountryID)); CreateCustomer("Andrew", CreateCity("Washington D.C.", usa.CountryID)); CreateCustomer("Daniel", CreateCity("Miami", usa.CountryID)); CreateCity("Cardiff", uk.CountryID); CreateCity("Liverpool", uk.CountryID); CreateCity("Oxford", uk.CountryID); CreateCity("Atlanta", usa.CountryID); CreateCity("Houston", usa.CountryID); CreateCity("Phoenix", usa.CountryID); } Customer CreateCustomer(string name, City city) { var c = new Customer() { CustomerName = name, CityID = city.CityID, CountryID = city.CountryID, CustomerID = Customers.Count }; Customers.Add(c); return c; } Country CreateCountry(string name) { var c = new Country() { CountryName = name }; c.CountryID = Countries.Count; Countries.Add(c); return c; } City CreateCity(string name, int countryID) { var c = new City() { CityName = name, CountryID = countryID, CityID = Cities.Count }; Cities.Add(c); return c; } } public class Customer { public int CustomerID { get; set; } public string CustomerName { get; set; } public int CountryID { get; set; } public int CityID { get; set; } } public class Country { public int CountryID { get; set; } public string CountryName { get; set; } } public class City { public int CityID { get; set; } public string CityName { get; set; } public int CountryID { get; set; } }
WebSite/Default.aspx
ASPx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <%@ Register Assembly="DevExpress.Web.v15.1, Version=15.1.15.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" Namespace="DevExpress.Web" TagPrefix="dx" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>How to implement cascaded combobox columns in ASPxGridView without using templates </title> <style type="text/css"> .grid { margin: 0 auto; } </style> <script type="text/javascript"> function CountriesCombo_SelectedIndexChanged(s, e) { grid.GetEditor("CityID").PerformCallback(s.GetValue()); } </script> </head> <body> <form id="form1" runat="server"> <dx:ASPxGridView ID="Grid" runat="server" AutoGenerateColumns="false" DataSourceID="Customers" Width="800" CssClass="grid" KeyFieldName="CustomerID" ClientInstanceName="grid" OnCellEditorInitialize="Grid_CellEditorInitialize"> <Columns> <dx:GridViewCommandColumn Width="100" ShowNewButton="true" ShowEditButton="true"/> <dx:GridViewDataColumn FieldName="CustomerID" Visible="false" SortOrder="Descending" /> <dx:GridViewDataTextColumn FieldName="CustomerName" Width="200"> <PropertiesTextEdit> <ValidationSettings RequiredField-IsRequired="true" Display="Dynamic" /> </PropertiesTextEdit> </dx:GridViewDataTextColumn> <dx:GridViewDataComboBoxColumn Caption="Country" FieldName="CountryID" Width="200"> <PropertiesComboBox DataSourceID="Countries" ValueField="CountryID" ValueType="System.Int32" TextField="CountryName" EnableSynchronization="False" IncrementalFilteringMode="StartsWith"> <ValidationSettings RequiredField-IsRequired="true" Display="Dynamic" /> <ClientSideEvents SelectedIndexChanged="CountriesCombo_SelectedIndexChanged" /> </PropertiesComboBox> </dx:GridViewDataComboBoxColumn> <dx:GridViewDataComboBoxColumn Caption="City" FieldName="CityID" Width="200"> <PropertiesComboBox DataSourceID="AllCities" ValueField="CityID" ValueType="System.Int32" TextField="CityName" EnableSynchronization="False" IncrementalFilteringMode="StartsWith"> <ValidationSettings RequiredField-IsRequired="true" Display="Dynamic" /> </PropertiesComboBox> </dx:GridViewDataComboBoxColumn> </Columns> <Settings ShowGroupPanel="true" /> <SettingsEditing Mode="Inline" /> </dx:ASPxGridView> <asp:ObjectDataSource ID="Customers" runat="server" TypeName="DataProvider" SelectMethod="GetCustomers" InsertMethod="InsertCustomer" UpdateMethod="UpdateCustomer"> <InsertParameters> <asp:Parameter Name="CustomerName" Type="String" /> <asp:Parameter Name="CountryID" Type="Int32" /> <asp:Parameter Name="CityID" Type="Int32" /> </InsertParameters> <UpdateParameters> <asp:Parameter Name="CustomerID" Type="Int32" /> <asp:Parameter Name="CustomerName" Type="String" /> <asp:Parameter Name="CountryID" Type="Int32" /> <asp:Parameter Name="CityID" Type="Int32" /> </UpdateParameters> </asp:ObjectDataSource> <asp:ObjectDataSource ID="Countries" runat="server" TypeName="DataProvider" SelectMethod="GetCountries" /> <asp:ObjectDataSource ID="AllCities" runat="server" TypeName="DataProvider" SelectMethod="GetCities" /> <asp:ObjectDataSource ID="Cities" runat="server" TypeName="DataProvider" SelectMethod="GetCities"> <SelectParameters> <asp:Parameter Name="CountryID" Type="Int32" /> </SelectParameters> </asp:ObjectDataSource> </form> </body> </html>
WebSite/Default.aspx.cs(vb)
C#
using System; using DevExpress.Web; public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) Grid.StartEdit(0); } protected void Grid_CellEditorInitialize(object sender, ASPxGridViewEditorEventArgs e) { if (e.Column.FieldName == "CityID") { var combo = (ASPxComboBox)e.Editor; combo.Callback += new CallbackEventHandlerBase(combo_Callback); var grid = e.Column.Grid; if (!combo.IsCallback) { var countryID = -1; if (!grid.IsNewRowEditing) countryID = (int)grid.GetRowValues(e.VisibleIndex, "CountryID"); FillCitiesComboBox(combo, countryID); } } } private void combo_Callback(object sender, CallbackEventArgsBase e) { var countryID = -1; Int32.TryParse(e.Parameter, out countryID); FillCitiesComboBox(sender as ASPxComboBox, countryID); } protected void FillCitiesComboBox(ASPxComboBox combo, int countryID) { combo.DataSourceID = "Cities"; Cities.SelectParameters["CountryID"].DefaultValue = countryID.ToString(); combo.DataBindItems(); combo.Items.Insert(0, new ListEditItem("", null)); // Null Item } }

Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.