This example demonstrates how to implement cascading combo box editors within ASPxGridView.
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>
JavaScriptfunction 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
- ASPxGridView
- SelectedIndexChanged
- GridViewDataComboBoxColumn
- PerformCallback
- Callback
- CellEditorInitialize
Files to Look At
- DataProvider.cs (VB: DataProvider.vb)
- Default.aspx (VB: Default.aspx)
- Default.aspx.cs (VB: Default.aspx.vb)
More Examples
- Cascading Editors Demo
- ASPxGridView - How to implement cascading comboboxes in Batch Edit mode
- MVC ComboBox Extension - Cascading Combo Boxes
Example Code
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; }
}
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>
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
}
}