# Devexpress Blazor Combobox

> Build and configure the DevExpress Blazor ComboBox (DxComboBox) — a drop-down/select editor for Blazor Server, WebAssembly, and Hybrid apps. Use for data binding (sync/async), searching/filtering, grouping, virtualization, multi-column item lists, templates (item/edit box), validation in EditForm, Clear button and custom buttons, and cascading combo boxes. Also use for DxComboBox, combo box, drop…

- **Type:** Skill
- **Install:** `agentstack add skill-devexpress-agent-skills-devexpress-blazor-combobox`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [DevExpress](https://agentstack.voostack.com/s/devexpress)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [DevExpress](https://github.com/DevExpress)
- **Source:** https://github.com/DevExpress/agent-skills/tree/main/plugins/dx-blazor/skills/devexpress-blazor-combobox
- **Website:** https://www.devexpress.com

## Install

```sh
agentstack add skill-devexpress-agent-skills-devexpress-blazor-combobox
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# DevExpress Blazor ComboBox

`DxComboBox` is a text editor with a searchable drop-down list. It binds to strongly-typed collections or custom objects, supports multi-column layouts, grouping, virtual scrolling, cascading dropdowns, and fully customizable item and edit-box templates.

## When to Use This Skill

- Add a single-selection dropdown or selector to a Blazor form
- Bind to any `IEnumerable`, `IQueryable`, or async collection
- Enable live search/filter as the user types
- Display grouped items with a group header
- Create cascading (dependent) dropdowns
- Show multiple columns in the drop-down list
- Customise item rendering via `ItemDisplayTemplate` or `EditBoxDisplayTemplate`
- Add a Clear button, custom command buttons, or placeholder text
- Validate ComboBox selection inside a standard ``
- Use virtual scrolling for large lists

## Prerequisites & Installation

### NuGet Package

| Package | Purpose |
|---|---|
| `DevExpress.Blazor` | ComboBox + all standard Blazor UI components |

```bash
# Install from NuGet.org:
dotnet add package DevExpress.Blazor
```

### Setup (existing project)

1. Register DevExpress services in `Program.cs`:
   ```csharp
   builder.Services.AddDevExpressBlazor();
   ```
    > **v26.1 note**: `DevExpress.Blazor` no longer includes `options.BootstrapVersion` or `DevExpress.Blazor.BootstrapVersion`. Do not generate either API.
2. Apply a theme and add client scripts in `App.razor`:
   ```razor
   @DxResourceManager.RegisterTheme(Themes.Fluent)
   @DxResourceManager.RegisterScripts()
   ```
3. Add the namespace to `_Imports.razor`:
   ```razor
   @using DevExpress.Blazor
   ```

## Before You Start — Ask the Developer

Ask these questions **before** generating code:

1. **Render mode**: Are you using `InteractiveServer`, `InteractiveWebAssembly`, or `InteractiveAuto`? (`DxComboBox` does not function in Static SSR.)
2. **Is this a new project or an existing one?** New projects can use the DevExpress Template Kit; existing ones need manual setup above.
3. **Data type**: Are you binding to a simple `IEnumerable` (or primitive), a list of custom objects, an `IQueryable`, or loading data asynchronously?
4. **Value type**: Is the bound `Value` the same type as the data items (`TData == TValue`) or a different key type (e.g., `int` ID from a `List`)?
5. **Custom objects**: If binding to custom objects, have you overridden `Equals` and `GetHashCode` in your model? (Required for correct item matching.)
6. **Features needed**: Do you need search/filter, grouping, multiple columns, cascading, templates, or validation?

## Component Overview

```razor
@* Minimal example: string list *@


@code {
    IEnumerable Cities = new List { "London", "Berlin", "Paris" };
    string SelectedCity { get; set; }
}
```

**Key generic parameters**:
- `TData` — the type of items in the `Data` collection  
- `TValue` — the type of the bound `Value`; equals `TData` when binding to the whole object

## Documentation & Navigation Guide

| Topic | Reference File | When to load |
|-------|---------------|--------------|
| Getting Started (setup, first ComboBox) | [references/getting-started.md](references/getting-started.md) | New project setup or first-time use |
| Data Binding (simple, custom objects, async, virtual scroll) | [references/data-binding.md](references/data-binding.md) | Binding to data or setting `Value` |
| Search, Filter, Grouping, Disabled Items | [references/data-shaping.md](references/data-shaping.md) | Configuring search or grouping |
| Multiple Columns | [references/multiple-columns.md](references/multiple-columns.md) | Multi-column drop-down layout |
| Appearance Customization & Templates | [references/appearance-and-templates.md](references/appearance-and-templates.md) | Styling, size modes, templates |
| Buttons & Cascading | [references/buttons-and-cascading.md](references/buttons-and-cascading.md) | Clear button, custom buttons, cascading ComboBoxes |
| Validation | [references/validation.md](references/validation.md) | `` integration |

## Key Properties & API Surface

### `DxComboBox` — most-used members

| Property / Event | Type | Description |
|---|---|---|
| `Data` | `IEnumerable` | Binds the drop-down list to a data source |
| `DataAsync` | `Func>>` | Asynchronous data loading |
| `Value` / `@bind-Value` | `TValue` | Selected value; use `@bind-Value` for two-way binding |
| `ValueChanged` | `EventCallback` | Fired when the value changes |
| `TextFieldName` | `string` | Field name to display as item text (for custom object collections) |
| `KeyFieldName` | `string` | Field used as the item key (decouples `TData` from `TValue`) |
| `KeyFieldNames` | `string[]` | Multiple key fields for composite keys |
| `GroupFieldName` | `string` | Field used to group items in the list |
| `DisabledFieldName` | `string` | Boolean field that marks items as disabled |
| `NullText` | `string` | Placeholder displayed when value is null |
| `ClearButtonDisplayMode` | `DataEditorClearButtonDisplayMode` | Controls Clear button visibility (`Auto`, `Always`, `Never`) |
| `ShowDropDownButton` | `bool` | Shows/hides the built-in drop-down toggle button |
| `AllowUserInput` | `bool` | Allows typing a custom value not in the list |
| `SearchMode` | `ListSearchMode` | `AutoSearch` (default), `Disabled` |
| `SearchFilterCondition` | `ListSearchFilterCondition` | `Contains`, `StartsWith`, `Equals` |
| `SearchTextParseMode` | `ListSearchTextParseMode` | How multiple words are combined |
| `SearchDelay` | `int` | Debounce delay (ms) before search fires |
| `EditFormat` | `string` | Format string for the edit box value in multi-column mode |
| `DropDownDirection` | `DropDownDirection` | `Down` (default), `Up` |
| `DropDownWidthMode` | `DropDownWidthMode` | `ContentOrEditorWidth` (default), `ContentWidth`, `EditorWidth` |
| `SizeMode` | `SizeMode` | `Small`, `Medium` (default), `Large` |
| `DataLoadMode` | `ListDataLoadMode` | `Auto` (default), `OnDemand` |
| `ListRenderMode` | `ListRenderMode` | `Default`, `Virtual` (virtual scrolling) |
| `InputCssClass` | `string` | CSS class applied to the input element |
| `InputId` | `string` | HTML `id` of the input element (for label association) |
| `ItemDisplayTemplate` | `RenderFragment>` | Customises drop-down item rendering |
| `EditBoxDisplayTemplate` | `RenderFragment>` | Customises selected-value rendering in the edit box |
| `ColumnCellDisplayTemplate` | `RenderFragment>` | Customises all column cells in multi-column mode |
| `ValidateBy` | `ComboBoxValidateBy` | `Text` or `Value` — which property is validated |

### `DxListEditorColumn` — for multi-column drop-down

| Property | Type | Description |
|---|---|---|
| `FieldName` | `string` | Data source field for this column |
| `Caption` | `string` | Column header text |
| `Width` | `string` | Column width (CSS value, e.g. `"50px"`) |
| `SearchEnabled` | `bool` | Include this column in search operations |
| `CellDisplayTemplate` | `RenderFragment>` | Per-column cell template |

### Enums

| Enum | Values |
|---|---|
| `DataEditorClearButtonDisplayMode` | `Auto`, `Always`, `Never` |
| `ListSearchMode` | `AutoSearch`, `Disabled` |
| `ListSearchFilterCondition` | `Contains`, `StartsWith`, `Equals` |
| `ListDataLoadMode` | `Auto`, `OnDemand` |
| `ListRenderMode` | `Default`, `Virtual` |
| `DropDownDirection` | `Down`, `Up` |
| `DropDownWidthMode` | `ContentOrEditorWidth`, `ContentWidth`, `EditorWidth` |
| `SizeMode` | `Small`, `Medium`, `Large` |

## Common Patterns

### Pattern 1 — Bind to a Custom Object Collection

When `TData` is a custom class, set `TextFieldName`, and override `Equals`/`GetHashCode` in the model (or use `KeyFieldName` to avoid this):

```razor


@code {
    Person SelectedPerson { get; set; } = Staff.DataSource[0];
}
```

Model requirement when `TData == TValue`:
```csharp
public class Person {
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Text => $"{FirstName} {LastName}";

    public override bool Equals(object obj) =>
        obj is Person p && Id == p.Id;

    public override int GetHashCode() => HashCode.Combine(Id);
}
```

### Pattern 2 — Search & Filter with Group Data

```razor

```

### Pattern 3 — Multi-Column Drop-Down

```razor

    
        
        
        
    

```

## Troubleshooting

| Symptom | Likely Cause | Fix |
|---|---|---|
| Drop-down doesn't open / events don't fire | Static SSR render mode | Add `@rendermode InteractiveServer` (or WASM/Auto) to the page or component |
| Selected item not highlighted in drop-down | Custom object without `Equals`/`GetHashCode`, or different `TData`/`TValue` | Override `Equals`/`GetHashCode`, or use `KeyFieldName` to decouple types |
| Items show `ClassName` instead of text | `TextFieldName` not set for custom object collection | Set `TextFieldName` to the display field name |
| Search doesn't filter | `SearchMode` defaults to `AutoSearch` but `AllowUserInput` blocks it | Verify `SearchMode="ListSearchMode.AutoSearch"` is set; check `AllowUserInput` |
| `ValueChanged` doesn't update cascade list | Using `@bind-Value` instead of `Value` + `ValueChanged` separately | Use `Value="@val" ValueChanged="@(v => HandleChange(v))"` for cascading |
| Drop-down direction wrong | Default `DropDownDirection.Down` | Set `DropDownDirection="DropDownDirection.Up"` if at the bottom of the page |
| Virtual scrolling item missing | `ListRenderMode.Virtual` + `DataLoadMode.OnDemand` limitation | Known limitation: selected item outside viewport may not scroll into view |
| `"DxComboBox requires a value for the 'Expression' property"` in `EditForm` | Editor not using two-way binding | Replace `Value="@val"` with `@bind-Value="@val"`, or explicitly set `ValueExpression="@(() => val)"` |
| `"The type arguments cannot be inferred from the usage"` for `DataAsync` | Wrong function signature for async data loading | Ensure the function returns `Task>` and accepts a `CancellationToken` parameter |
| `"Unhandled exception on the current circuit"` with no detail | `CircuitOptions.DetailedErrors` not set | Add `builder.Services.Configure(o => o.DetailedErrors = true);` in `Program.cs` (development only) |
| `"Component parameter 'ValueChanged' is used two or more times"` compile error | `@bind-Value` and `ValueChanged` used together | Use `@bind-Value="@val"` for two-way binding, or `Value="@val" ValueChanged="@handler"` — never both simultaneously |
| `dx-blazor.js` not found (404) behind a reverse proxy | Reverse proxy strips the app base path | Add `app.UsePathBase("/subpath")` before `app.MapBlazorHub()`, or set `` in `App.razor` |
| Static assets return 404 (`dx-blazor.css`, `dx-blazor.js`) | `UseStaticWebAssets()` not called | Add `app.UseStaticWebAssets();` in `Program.cs` before `app.UseStaticFiles()` |
| `"Could not find 'X' in 'window.DxBlazor'"` JavaScript error | Stale browser-cached JS from an older DevExpress version | Hard-refresh the browser (Ctrl+Shift+R), clear site data, or verify all DevExpress NuGet packages are the same version |
| `"Cannot pass the parameter 'X' to component 'Y' with rendermode"` | Non-serializable parameter passed across a render mode boundary | Move the component to a child `.razor` file with its own `@rendermode` directive; pass only serializable parameters |

## Constraints & Rules

CRITICAL: Follow these rules in every interaction:

0. **Never invent API**: If a property, method, event, or feature is not documented in this skill or its references, do **not** assume it exists. When asked about an unfamiliar API, first try to verify it using the DevExpress documentation MCP (`devexpress_docs_search`) or the local `apidoc/` folder. Only after checking: if confirmed, use the API; if not found, explicitly state that it does not appear to be part of the `DxComboBox` API. Do not warn that a feature "may have been introduced in a recent version" as a way to justify inventing it.
1. **Build verification**: After making changes, always run `dotnet build` and check for errors before reporting success.
2. **NuGet packages**: Use only `DevExpress.Blazor`. Do not guess alternative package names.
3. **Namespace imports**: Always include `@using DevExpress.Blazor` in `_Imports.razor` or the component file.
4. **Version consistency**: All DevExpress packages in a project must use the same version. Do not mix versions.
5. **License**: DevExpress requires a valid license. Remind the user if they encounter license-related build errors.
6. **No destructive changes**: Preserve existing using statements, class structure, and unrelated code. Only add or modify what is necessary.
7. **Interactivity**: `DxComboBox` requires an interactive render mode. If the page uses Static SSR, add `@rendermode InteractiveServer` (or appropriate mode) to the page or a parent component.
8. **Custom objects**: When `TData` is a custom class and `TData == TValue`, the class **must** override `Equals` and `GetHashCode` for item selection to work correctly. Alternatively, use `KeyFieldName` to avoid this requirement.

## Using DevExpress Documentation MCP

If the DevExpress Docs MCP server is available (check for `devexpress_docs_search` and `devexpress_docs_get_content` tools), use it to supplement this skill:

1. **Search for documentation**: `devexpress_docs_search(technology="Blazor", query="ComboBox ")`
2. **Fetch full content**: `devexpress_docs_get_content(url="")`

**When to use MCP vs. built-in references:**
- Use built-in references for: Getting started, common patterns, key properties covered in this skill.
- Use MCP for: Advanced scenarios, version-specific API changes, features not covered here, or when you need exact method signatures.
- Always prefer MCP for: Confirming event argument types, enum values, or interface members you are not 100% certain about.

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [DevExpress](https://github.com/DevExpress)
- **Source:** [DevExpress/agent-skills](https://github.com/DevExpress/agent-skills)
- **License:** MIT
- **Homepage:** https://www.devexpress.com

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-devexpress-agent-skills-devexpress-blazor-combobox
- Seller: https://agentstack.voostack.com/s/devexpress
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
