Skip to main content
All docs
V25.1
  • Cascading Comboboxes

    • 3 minutes to read

    The <DxComboBox> allows you to create cascade lists - populate one ComboBox with items based on the user selection from another ComboBox. Use the Value property to access the selected item. To respond to the selected item change, handle the ValueChanged event.

    ComboBox Cascade Logic

    @using CountryCityData
    
    <div class="row cw-480">
        <div class="col-md-6">
            <label for="cbCountryName" class="mb-1">
                Country Name
            </label>
            <DxComboBox Data="@Countries"
                        TextFieldName="@nameof(Country.CountryName)"
                        Value="@CurrentCountry"
                        ValueChanged="@((Country country) => SelectedCountryChanged(country))"
                        AllowUserInput="true">
                        InputId="cbCountryName">
            </DxComboBox>
        </div>
        <div class="col-md-6">
            <label for="cbCityName" class="mb-1">
                City Name
            </label>
            <DxComboBox Data="@CurrentCountryCities"
                        TextFieldName="@nameof(City.CityName)"
                        @bind-Value="@CurrentCity"
                        AllowUserInput="true"
                        InputId="cbCityName" >
            </DxComboBox>
        </div>
    </div>
    
    @code {
        List<Country> Countries { get; set; } = CountryData.Countries;
        List<City> CurrentCountryCities { get; set; } = new List<City>();
        Country CurrentCountry { get; set; } = CountryData.Countries[1];
        City CurrentCity { get; set; } = CityData.Cities[4];
    
        protected override void OnInitialized() {
            base.OnInitialized();
            SelectedCountryChanged(CurrentCountry);
        }
    
        void SelectedCountryChanged(Country country) {
            CurrentCountry = country;
            CurrentCountryCities = CityData.Cities.FindAll(city => city.CountryId == CurrentCountry.Id);
            CurrentCity = CurrentCountryCities[0];
        }
    }
    

    If you use the DataAsync or CustomData property to bind cascading ComboBoxes to data, you need to set a key to force the component to fetch data on re-render, or use the Data property instead of the DataAsync delegate. Refer to this breaking change for more information.

    <DxComboBox Data="FirstDataSource"
                ValueFieldName="@nameof(MyModel.ID)"
                TextFieldName="@nameof(MyModel.Name)"
                Value="@FirstValue" 
                ValueChanged="@((int? value) => { FirstValue = value; keyValue++;})" />
    
    <DxComboBox @key=@keyValue
                DataAsync="(cancellationToken) => LoadDataAsync(FirstValue, cancellationToken)"
                ValueFieldName="@nameof(MyModel.ID)"
                TextFieldName="@nameof(MyModel.Name)"
                @bind-Value="@SecondValue" />
    
    @code {
       int keyValue;
       IEnumerable<MyModel> FirstDataSource { get; set; }
       int? FirstValue { get; set; }
       string? SecondValue { get; set; }
       public class MyModel {
           public int ID { get; set; }
           public string Name { get; set; }
       }
       protected override void OnInitialized() {
           FirstDataSource = Enumerable.Range(0, 10).Select(i => new MyModel() { ID = i, Name = $"Name {i}" });        
       }
       public async Task<IEnumerable<string>> LoadDataAsync(int? value, CancellationToken cancellationToken = default(CancellationToken)) {
           if(!value.HasValue)
               return Enumerable.Empty<string>();
           return FirstDataSource.Where(i => i.ID % value == 0).Select(i => i.Name);
       }
    }
    

    Run Demo: ComboBox - Cascading Lists View Example: Grid - Implement Cascading ComboBoxes