
Syncfusion Blazor Multicolumn Combobox
- 223 installs
- 4 repo stars
- Updated July 28, 2026
- syncfusion/blazor-ui-components-skills
Use syncfusion-blazor-multicolumn-combobox for development tasks
About
syncfusion-blazor-multicolumn-combobox: A skill for development. This provides functionality for development workflows.
- syncfusion-blazor-multicolumn-combobox
Syncfusion Blazor Multicolumn Combobox by the numbers
- 223 all-time installs (skills.sh)
- +14 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #1,788 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/syncfusion/blazor-ui-components-skills --skill syncfusion-blazor-multicolumn-comboboxAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 223 |
|---|---|
| repo stars | ★ 4 |
| Last updated | July 28, 2026 |
| Repository | syncfusion/blazor-ui-components-skills ↗ |
What it does
Use syncfusion-blazor-multicolumn-combobox for development tasks
Files
Implementing Syncfusion Blazor MultiColumn ComboBox
The MultiColumn ComboBox component is a dropdown control that displays data in multiple columns with built-in features like filtering, selection, paging, virtualization, grouping, and customization. It combines the capabilities of a traditional ComboBox with a data grid layout.
When to Use This Skill
Use this skill when you need to:
- Display structured data in a dropdown with multiple columns
- Implement filtering and search capabilities across column data
- Bind to local or remote data sources (Web API, OData)
- Support value selection with flexible binding options
- Add paging, virtualization, or grouping to large datasets
- Customize appearance, styling, and validation in forms
- Implement accessible, keyboard-navigable dropdowns
- Create server-side or web app integrated MultiColumn ComboBox components
Component Overview
The MultiColumn ComboBox provides:
- Multi-column layout for displaying complex data structures
- Advanced filtering (local/remote, case-sensitive, multi-column)
- Data binding (local arrays, Web API, OData, custom adaptors)
- Selection modes with value binding (simple, tuple, complex objects)
- Performance features (paging, virtualization, offline mode)
- Customization (templates, styling, appearance)
- Form integration with validation and floating labels
- Accessibility with WCAG compliance and keyboard support
---
Documentation Navigation Guide
Getting Started
📄 Read: references/getting-started.md
- Installation and package setup
- Basic MultiColumn ComboBox implementation
- Template structure
- Creating your first MultiColumn ComboBox
Columns and Data Display
📄 Read: references/columns-and-templates.md
- Column definition and configuration
- Column templates and formatting
- Column headers and text alignment
- Grid settings (row height, alternating rows)
Data Binding Options
📄 Read: references/data-binding.md
- Local data binding (arrays, collections)
- Web API and OData binding
- Action events (ActionBegin, ActionComplete, ActionFailure)
- Observable collections and dynamic binding
Filtering and Search
📄 Read: references/filtering-and-search.md
- Filter types and custom filtering logic
- Multi-column filtering techniques
- Case-sensitive filtering
- Remote data filtering
Selection and Value Binding
📄 Read: references/selection-and-values.md
- Single and multiple value binding
- Value selection patterns
- Custom values and enum binding
- Working with tuples and complex objects
Advanced Features and Settings
📄 Read: references/features-and-settings.md
- Paging and virtualization for performance
- Grouping data by columns
- Popup settings (size, position, resize)
- Placeholder and floating labels
Styling and Appearance
📄 Read: references/styling-and-appearance.md
- CSS classes and custom styling
- Placeholder and float label customization
- Appearance tweaks (alt rows, grid lines, text wrapping)
- Theme integration
Accessibility and Localization
📄 Read: references/accessibility-localization.md
- WCAG compliance and keyboard navigation
- ARIA attributes and screen reader support
- Form validation integration
- Localization for international apps
Advanced Patterns and Integration
📄 Read: references/advanced-patterns.md
- Server-side and web app integration
- Custom data adaptors
- Enum and dynamic object binding
- Offline mode and performance optimization
---
Quick Start Example
Here's a minimal MultiColumn ComboBox implementation:
@using Syncfusion.Blazor.MultiColumnComboBox
<SfMultiColumnComboBox TValue="string" TItem="OrderData"
DataSource="@OrderList"
TextField="CustomerName"
ValueField="OrderID"
Placeholder="Select an order">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="OrderID" Header="Order ID" Width="100px"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="CustomerName" Header="Customer" Width="150px"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="TotalAmount" Header="Amount" Width="100px" Format="C2"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
private List<OrderData> OrderList = new();
protected override void OnInitialized()
{
OrderList = new()
{
new OrderData { OrderID = "1001", CustomerName = "Alice Johnson", TotalAmount = 150.50m },
new OrderData { OrderID = "1002", CustomerName = "Bob Smith", TotalAmount = 280.75m },
new OrderData { OrderID = "1003", CustomerName = "Carol White", TotalAmount = 420.00m }
};
}
public class OrderData
{
public string OrderID { get; set; }
public string CustomerName { get; set; }
public decimal TotalAmount { get; set; }
}
}---
Common Patterns
1. Filtering User Input
When users type in the search box, the ComboBox filters items. Use the AllowFiltering property and customize with FilterType.
<SfMultiColumnComboBox TValue="string" TItem="ProductData"
DataSource="@Products"
AllowFiltering="true"
FilterType="FilterType.Contains">
<MultiColumnComboboxColumns>
<!-- Columns -->
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>2. Remote Data Loading
Bind to Web API or OData services using the Query property with data adaptor.
<SfMultiColumnComboBox TValue="string" TItem="OrderData"
Query="@DataQuery">
<MultiColumnComboboxColumns>
<!-- Columns -->
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
private Query DataQuery = new Query().From("Orders").Select(new List<string> { "OrderID", "CustomerName" });
}3. Handling Selection Change
Use the ValueChange event to respond when user selects an item.
<SfMultiColumnComboBox TValue="string" TItem="OrderData"
ValueChange="@OnValueChange">
<MultiColumnComboboxColumns>
<!-- Columns -->
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
private void OnValueChange(ValueChangeEventArgs<string, OrderData> args)
{
// args.Value = selected value
// args.ItemData = selected item object
}
}4. Paging Large Datasets
Enable paging to show limited rows and load more on demand.
<SfMultiColumnComboBox TValue="string" TItem="OrderData"
AllowPaging="true"
PageSize="10">
<MultiColumnComboboxColumns>
<!-- Columns -->
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>5. Form Validation
Integrate with EditForm for validation and required field checks.
<EditForm Model="@FormModel">
<SfMultiColumnComboBox TValue="string" TItem="OrderData"
@bind-Value="@FormModel.SelectedOrderID"
DataSource="@Orders">
<MultiColumnComboboxColumns>
<!-- Columns -->
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
<ValidationMessage For="@(() => FormModel.SelectedOrderID)" />
</EditForm>---
Key Properties
TextField | Maps display text field | TextField="Name" | | ValueField | Maps value field | ValueField="ID"` |
| Property | Description | Example |
|---|---|---|
DataSource | Data collection to bind | DataSource="@Products" |
TextField | Maps display text field | TextField="Name" |
ValueField | Maps value field | ValueField="ID" |
Value / @bind-Value | Gets/sets selected value | @bind-Value="@SelectedID" |
AllowFiltering | Enables search/filter capability | AllowFiltering="true" |
FilterType | Filter matching behavior | FilterType="FilterType.Contains" |
Placeholder | Input hint text | Placeholder="Select..." |
AllowPaging | Enables paging | AllowPaging="true" |
PageSize | Items per page (with paging) | PageSize="10" |
GroupByField | Groups items by field | GroupByField="Category" |
Query | Data query for remote sources | Query="@new Query().From('Orders')" |
Disabled / ReadOnly | Control states | `Dis |
---
Common Use Cases
1. Order Selection Form - Users pick orders from a grid-like dropdown with order ID, customer, and amount 2. Employee Lookup - Search employees by name, email, or ID across multiple columns 3. Product Catalog - Display products with category, price, and stock in a multi-column dropdown 4. Location Selector - Select cities/regions with country, state, and timezone information 5. Account Selection - Pick from accounts showing number, type, and balance in one dropdown
---
What's Next?
Start with Getting Started to install and create your first MultiColumn ComboBox, then explore other guides based on your needs. Each reference provides complete code examples and edge cases.
Questions? Check the relevant reference guide for your specific use case.
Accessibility and Localization
Table of Contents
- WCAG Compliance
- Keyboard Navigation
- ARIA Attributes
- Screen Reader Support
- Focus Management
- Color Contrast
- Localization
- Form Validation Accessibility
- Examples
---
WCAG Compliance
WCAG 2.1 Level AA
The Syncfusion MultiColumn ComboBox meets WCAG 2.1 AA standards:
- ✓ Perceivable: Visible labels, sufficient color contrast
- ✓ Operable: Keyboard accessible, focus indicators
- ✓ Understandable: Clear labels, predictable behavior
- ✓ Robust: Compatible with assistive technologies
Ensure Accessibility
<!-- ✅ ACCESSIBLE -->
<label for="product-selector">Select Product:</label>
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
ID="product-selector"
DataSource="@Products"
Placeholder="Choose a product">
<MultiColumnComboboxColumns>
<!-- Columns -->
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
<!-- ❌ NOT ACCESSIBLE -->
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@Products">
<MultiColumnComboboxColumns>
<!-- No label, no ID -->
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>---
Keyboard Navigation
Default Keyboard Support
| Key | Action |
|---|---|
Tab | Move to ComboBox |
Space / Enter | Open dropdown |
↓ Arrow | Navigate down |
↑ Arrow | Navigate up |
Home | First item |
End | Last item |
Enter | Select item |
Escape | Close dropdown |
Backspace | Clear input |
Keyboard-Only Navigation
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@Products"
AllowFiltering="true">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="ProductID" Header="ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="ProductName" Header="Product"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>User Journey (Keyboard Only): 1. Press Tab to focus input 2. Type to filter: "lap" for laptop 3. Press ↓ to navigate results 4. Press Enter to select 5. Continue with Tab to next field
---
ARIA Attributes
ARIA attributes enhance accessibility for screen readers:
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@Products"
Placeholder="Select a product">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="ProductID" Header="ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="ProductName" Header="Product"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>ARIA Label Best Practices
<!-- ✅ GOOD: Clear, descriptive label -->
<label for="customer-combo">Select Customer:</label>
<SfMultiColumnComboBox TValue="int" TItem="CustomerData"
ID="customer-combo"
DataSource="@Customers"
Placeholder="Select customer for order">
<MultiColumnComboboxColumns>
<!-- Columns -->
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
<!-- ❌ BAD: No label, no ID -->
<SfMultiColumnComboBox TValue="int" TItem="CustomerData"
DataSource="@Customers">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="CustomerID" Header="ID"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>---
Screen Reader Support
Component Announcement
When dropdown opens, screen readers announce:
- Component name and type
- Number of items
- Current selection (if any)
- Instructions for interaction
Enhance with Description
<fieldset>
<legend>Order Selection</legend>
<div>
<label for="order-selector">Select Order:</label>
<small id="order-help">Choose an order from the list</small>
<SfMultiColumnComboBox TValue="int" TItem="OrderData"
ID="order-selector"
DataSource="@Orders"
TextField="CustomerName"
ValueField="OrderID"
InputAttributes="@(new Dictionary<string, object> { {"aria-describedby", "order-help"} })"
Placeholder="Choose an order from the list">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="OrderID" Header="Order ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="CustomerName" Header="Customer"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
</div>
</fieldset>--- s Management
Custom Focus Styling
<style>
.e-
## Focumulticolumn-combobox .e-input:focus {
outline: 2px solid #0066cc;
outline-offset: 2px;
}
.e-multicolumn-combobox .e-input-group.e-focus {
box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.25);
}
</style>Visible Focus Outline
<!-- ✅ ACCESSIBLE: Focus outline clearly visible -->
<SfMultiColumnComboBox TValue="int" TItem="ProductData" DataSource="@Products">
<MultiColumnComboboxColumns>
<!-- Default focus styling works -->
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
<!-- ❌ INACCESSIBLE: Focus outline hidden -->
<style>
.e-multicolumn-combobox .e-input:focus {
outline: none; /* Don't remove! */
}
</style>Tab Order Management
<!-- Controls tab order using HtmlAttributes -->
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@Products"
TextField="ProductName"
ValueField="ProductID"
HtmlAttributes="@(new Dictionary<string, object> { {"tabindex", "1"} })">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="ProductID" Header="ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="ProductName" Header="Product"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
<button tabindex="2">Submit</button>---
Color Contrast
Sufficient Contrast Ratios
All text must meet WCAG AA standards (4.5:1 for normal text, 3:1 for large text):
<style>
/* ✅ GOOD: 4.5:1 contrast (black on white) */
.e-multicolumn-combobox .e-input {
color: #000000;
background-color: #ffffff;
}
/* ❌ BAD: Insufficient contrast (gray on white) */
.e-multicolumn-combobox .e-input {
color: #cccccc;
background-color: #ffffff;
}
</style>Form Validation Accessibility
Accessible Validation Messages
<EditForm Model="@OrderModel" OnValidSubmit="@HandleSubmit">
<DataAnnotationsValidator />
<div class="form-group">
<label for="order-select">Order Selection:</label>
<SfMultiColumnComboBox TValue="int" TItem="OrderData"
ID="order-select"
DataSource="@Orders"
TextField="CustomerName"
ValueField="OrderID"
@bind-Value="@OrderModel.SelectedOrderID"
InputAttributes="@GetInputAttributes()">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="OrderID" Header="Order ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="CustomerName" Header="Customer"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
<div id="order-error" class="invalid-feedback">
<ValidationMessage For="@(() => OrderModel.SelectedOrderID)" />
</div>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</EditForm>
@code {
private OrderModel OrderModel = new();
private List<OrderData> Orders = new();
public class OrderModel
{
[Required(ErrorMessage = "Please select an order")]
public int SelectedOrderID { get; set; }
}
}Error Announcement
<style>
.invalid-feedback {
display: block;
color: #dc3545;
font-size: 14px;
margin-top: 5px;
}
.form-group .e-input-group.e-error {
border-color: #dc3545;
}
.e-multicolumn-combobox.e-error .e-input-group {
border-color: #dc3545;
}
</style>
<!-- Screen reader announces errors -->
<div role="alert" class="invalid-feedback">
Order selection is required
</div>---
Examples
Fully Accessible Form
@page "/accessible-form"
@using Syncfusion.Blazor.DropDowns
<h2>Order Form MultiColumnComboBox TValue="int" TItem="CustomerData"
ID="customer-select"
DataSource="@Customers"
AllowFiltering="true"
Placeholder="Search customer..."
@bind-Value="@OrderForm.CustomerID">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="CustomerID" Header="ID" Width="60px"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="CustomerName" Header="Name" Width="180px"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="Email" Header="Email" Width="200px"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
<ValidationMessage For="@(() => OrderForm.CustomerID)" />
</div>
<div class="form-group">
<label for="product-select">
<span class="required">*</span> Product
</label>
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
ID="product-select"
DataSource="@Products"
AllowFiltering="true"
Placeholder="Search product..."
@bind-Value="@OrderForm.ProductID">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="ProductID" Header="ID" Width="60px"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="ProductName" Header="Product" Width="180px"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="Price" Header="Price" Width="100px" Format="C2"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnel for="product-select">
<span class="required">*</span> Product
</label>
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
ID="product-select"
DataSource="@Products"
AllowFiltering="true"
TextField="ProductName"
ValueField="ProductID"
Placeholder="Search product..."
InputAttributes="@(new Dictionary<string, object> { {"aria-label", "Select a product"} })"
@bind-Value="@OrderForm.ProductID">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="ProductID" Header="ID" Width="60px"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="ProductName" Header="Product" Width="180px"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="Price" Header="Price" Width="100px" Format="C2"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
<ValidationMessage For="@(() => OrderForm.ProductID)" />
</div>
</fieldset>
<button type="submit" class="btn btn-primary">Submit Order</button>
</EditForm>
<style>
.required {
color: #dc3545;
margin-right: 5px;
}
.form-group {
margin-bottom: 20px;
}
.form-group label {
display: block;
margin-bottom: 5px;
font-weight: 600;
color: #333;
}
.form-group small {
display: block;
margin-bottom: 8px;
color: #666;
font-size: 13px;
}
</style>
@code {
private OrderFormModel OrderForm = new();
private List<CustomerData> Customers = new();
private List<ProductData> Products = new();
protected override void OnInitialized()
{
Customers = new()
{
new CustomerData { CustomerID = 1, CustomerName = "John Doe", Email = "john@example.com" },
new CustomerData { CustomerID = 2, CustomerName = "Jane Smith", Email = "jane@example.com" }
};
Products = new()
{
new ProductData { ProductID = 1, ProductName = "Laptop", Price = 999.99m },
new ProductData { ProductID = 2, ProductName = "Mouse", Price = 29.99m }
};
}
private async Task HandleSubmit()
{
Console.WriteLine("Form submitted");
await Task.CompletedTask;
}
public class OrderFormModel
{
[Required(ErrorMessage = "Customer selection is required")]
public int CustomerID { get; set; }
[Required(ErrorMessage = "Product selection is required")]
public int ProductID { get; set; }
}
public class CustomerData
{
public int CustomerID { get; set; }
public string CustomerName { get; set; }
public string Email { get; set; }
}
public class ProductData
{
public int ProductID { get; set; }
public string ProductName { get; set; }
public decimal Price { get; set; }
}
}---
Next Steps
- Advanced styling: See references/styling-and-appearance.md
- Advanced patterns: See references/advanced-patterns.md
- Performance optimization: See references/features-and-settings.md
Advanced Patterns and Integration
Table of Contents
- Server-Side Integration
- Web App Integration
- Custom Data Adaptors
- Dynamic Object Binding
- Enum Data Binding
- Offline Mode
- Performance Optimization
- Advanced Scenarios
- Examples
---
Server-Side Integration
Blazor Server-Side
MultiColumn ComboBox automatically works with server-side Blazor:
@page "/server-multicolumn-combobox"
@using Syncfusion.Blazor.MultiColumnComboBox
<h3>Server-Side MultiColumn ComboBox</h3>
<SfMultiColumnComboBox TValue="int" TItem="OrderData"
DataSource="@Orders"
TextField="CustomerName"
ValueField="OrderID"
Placeholder="Select an order">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="OrderID" Header="Order ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="CustomerName" Header="Customer"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="TotalAmount" Header="Amount" Format="C2"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
private List<OrderData> Orders = new();
protected override async Task OnInitializedAsync()
{
// Load from server-side database
Orders = await FetchOrdersFromDatabase();
}
private async Task<List<OrderData>> FetchOrdersFromDatabase()
{
// Database query via EF Core
return new List<OrderData>
{
new OrderData { OrderID = 1001, CustomerName = "Alice", TotalAmount = 150.00m },
new OrderData { OrderID = 1002, CustomerName = "Bob", TotalAmount = 250.00m }
};
}
public class OrderData
{
public int OrderID { get; set; }
public string CustomerName { get; set; }
public decimal TotalAmount { get; set; }
}
}Real-Time Updates with SignalR
@implements IAsyncDisposable
@using Microsoft.AspNetCore.SignalR.Client
@using Syncfusion.Blazor.MultiColumnComboBox
@page "/realtime-multicolumn-combobox"
<SfMultiColumnComboBox TValue="int" TItem="LiveOrderData"
DataSource="@LiveOrders"
TextField="Status"
ValueField="OrderID">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="OrderID" Header="Order ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="Status" Header="Status"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
private HubConnection hubConnection;
private List<LiveOrderData> LiveOrders = new();
protected override async Task OnInitializedAsync()
{
hubConnection = new HubConnectionBuilder()
.WithUrl(Navigation.ToAbsoluteUri("/orderhub"))
.WithAutomaticReconnect()
.Build();
hubConnection.On<LiveOrderData>("ReceiveOrder", async (order) =>
{
LiveOrders.Add(order);
await InvokeAsync(() => StateHasChanged());
});
await hubConnection.StartAsync();
}
async ValueTask IAsyncDisposable.DisposeAsync()
{
if (hubConnection is not null)
{
await hubConnection.DisposeAsync();
}
}
public class LiveOrderData
{
public int OrderID { get; set; }
public string Status { get; set; }
}
}---
Web App Integration
Using with ASP.NET Core Endpoints
// Program.cs
builder.Services.AddScoped<OrderService>();
// OrderService.cs
public class OrderService
{
private readonly HttpClient _http;
public OrderService(HttpClient http)
{
_http = http;
}
public async Task<List<OrderData>> GetOrdersAsync()
{
return await _http.GetFromJsonAsync<List<OrderData>>("/api/orders");
}
}
// Page.razor
@inject OrderService OrderService
@using Syncfusion.Blazor.MultiColumnComboBox
<SfMultiColumnComboBox TValue="int" TItem="OrderData"
DataSource="@Orders"
TextField="CustomerName"
ValueField="OrderID">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="OrderID" Header="Order ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="CustomerName" Header="Customer"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
private List<OrderData> Orders = new();
protected override async Task OnInitializedAsync()
{
Orders = await OrderService.GetOrdersAsync();
}
}API Endpoint
[ApiController]
[Route("api/[controller]")]
public class OrdersController : ControllerBase
{
private readonly IOrderService _orderService;
[HttpGet]
public async Task<IActionResult> GetOrders()
{
var orders = await _orderService.GetAllOrdersAsync();
return Ok(orders);
}
[HttpGet("search")]
public async Task<IActionResult> SearchOrders([FromQuery] string searchTerm)
{
var orders = await _orderService.SearchOrdersAsync(searchTerm);
return Ok(orders);
}
}---
Custom Data Adaptors
Implement IDataService
public interface ICustomDataAdaptor
{
Task<List<T>> GetDataAsync<T>(DataManagerRequest dm);
}
public class DatabaseAdaptor : ICustomDataAdaptor
{
private readonly IDbContextFactory<ApplicationDbContext> _contextFactory;
public DatabaseAdaptor(IDbContextFactory<ApplicationDbContext> contextFactory)
{
_contextFactory = contextFactory;
}
public async Task<List<T>> GetDataAsync<T>(DataManagerRequest dm) where T : class
{
using var context = _contextFactory.CreateDbContext();
var query = context.Set<T>().AsQueryable();
// Apply filtering
if (dm.Where != null && dm.Where.Count > 0)
{
foreach (var filter in dm.Where)
{
query = ApplyFilter(query, filter);
}
}
// Apply paging
if (dm.Skip > 0)
query = query.Skip(dm.Skip);
if (dm.Take > 0)
query = query.Take(dm.Take);
return await query.ToListAsync();
}
private IQueryable<T> ApplyFilter<T>(IQueryable<T> query, WhereFilter filter) where T : class
{
// Custom filter logic
return query;
}
}Use Custom Adaptor
@inject ICustomDataAdaptor CustomAdaptor
@using Syncfusion.Blazor.MultiColumnComboBox
<SfMultiColumnComboBox TValue="int" TItem="OrderData"
DataSource="@FilteredOrders"
TextField="CustomerName"
ValueField="OrderID"
Filtering="@OnFiltering">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="OrderID" Header="Order ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="CustomerName" Header="Customer"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
private List<OrderData> FilteredOrders = new();
private async Task OnFiltering(FilteringEventArgs args)
{
args.PreventDefaultAction = true;
var dm = new DataManagerRequest { Skip = 0, Take = 20 };
FilteredOrders = await CustomAdaptor.GetDataAsync<OrderData>(dm);
}
}---
Dynamic Object Binding
Anonymous Types
@using Syncfusion.Blazor.MultiColumnComboBox
<SfMultiColumnComboBox TValue="int" TItem="dynamic"
DataSource="@DynamicData"
TextField="ProductName"
ValueField="ProductID"
Placeholder="Select item">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="ProductID" Header="ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="ProductName" Header="Product"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
private List<dynamic> DynamicData = new();
protected override void OnInitialized()
{
DynamicData = new()
{
new { ProductID = 1, ProductName = "Item A" },
new { ProductID = 2, ProductName = "Item B" }
};
}
}ExpandoObject
@using System.Dynamic
@using Syncfusion.Blazor.MultiColumnComboBox
<SfMultiColumnComboBox TValue="string" TItem="ExpandoObject"
DataSource="@ExpandoData"
TextField="Name"
ValueField="Name">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="Name" Header="Name"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="Price" Header="Price"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
private List<ExpandoObject> ExpandoData = new();
protected override void OnInitialized()
{
dynamic item1 = new ExpandoObject();
item1.ID = 1;
item1.Name = "Product A";
item1.Price = 99.99;
ExpandoData.Add(item1);
}
}---
Enum Data Binding
Status Enumeration
@using Syncfusion.Blazor.MultiColumnComboBox
<SfMultiColumnComboBox TValue="int" TItem="OrderData"
DataSource="@Orders"
TextField="Status"
ValueField="OrderID"
Placeholder="Select status">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="OrderID" Header="Order"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="Status" Header="Status"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
public enum OrderStatus
{
[Display(Name = "Pending")]
Pending = 0,
[Display(Name = "Processing")]
Processing = 1,
[Display(Name = "Shipped")]
Shipped = 2,
[Display(Name = "Delivered")]
Delivered = 3,
[Display(Name = "Cancelled")]
Cancelled = 4
}
public class OrderData
{
public int OrderID { get; set; }
public OrderStatus Status { get; set; }
}
private List<OrderData> Orders = new();
}---
Offline Mode
Cache Data Locally
@using Syncfusion.Blazor.Data
@using Syncfusion.Blazor.MultiColumnComboBox
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
Query="@GridQuery"
TextField="ProductName"
ValueField="ProductID"
Placeholder="Select product">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="ProductID" Header="ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="ProductName" Header="Product"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
private Query GridQuery = new Query().From("Products").Select(new List<string> { "ProductID", "ProductName" });
}Behavior:
- ✓ Data cached on first load
- ✓ Works offline if cached
- ✓ Auto-syncs when online
---
Performance Optimization
Virtual Scrolling with Large Datasets
@using Syncfusion.Blazor.MultiColumnComboBox
<SfMultiColumnComboBox TValue="int" TItem="OrderData"
DataSource="@Orders"
EnableVirtualization="true"
AllowFiltering="true"
TextField="CustomerName"
ValueField="OrderID"
Placeholder="Search orders...">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="OrderID" Header="Order ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="CustomerName" Header="Customer"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
private List<OrderData> Orders = new();
protected override void OnInitialized()
{
// Generate 10,000 items
Orders = Enumerable.Range(1, 10000)
.Select(i => new OrderData
{
OrderID = 1000 + i,
CustomerName = $"Customer {i}"
})
.ToList();
}
}Lazy Loading
@using Syncfusion.Blazor.MultiColumnComboBox
<SfMultiColumnComboBox TValue="int" TItem="OrderData"
DataSource="@FilteredOrders"
AllowFiltering="true"
Filtering="@OnFilter"
TextField="CustomerName"
ValueField="OrderID"
Placeholder="Type to load...">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="OrderID" Header="Order ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="CustomerName" Header="Customer"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
private List<OrderData> FilteredOrders = new();
private async Task OnFilter(FilteringEventArgs args)
{
args.PreventDefaultAction = true;
if (args.Text.Length < 3)
return;
// Load only matching records
FilteredOrders = await SearchOrdersAsync(args.Text);
}
private async Task<List<OrderData>> SearchOrdersAsync(string searchTerm)
{
// API call with search term
var response = await Http.GetFromJsonAsync<List<OrderData>>($"/api/orders/search?q={searchTerm}");
return response;
}
}---
Advanced Scenarios
Cascading MultiColumn ComboBoxes
@using Syncfusion.Blazor.MultiColumnComboBox
<div class="form-group">
<label>Category:</label>
<SfMultiColumnComboBox TValue="int" TItem="CategoryData"
DataSource="@Categories"
TextField="CategoryName"
ValueField="CategoryID"
@bind-Value="@SelectedCategoryID"
ValueChange="@OnCategoryChange">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="CategoryID" Header="ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="CategoryName" Header="Category"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
</div>
<div class="form-group">
<label>Product:</label>
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@FilteredProducts"
TextField="ProductName"
ValueField="ProductID"
Placeholder="Select a product">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="ProductID" Header="ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="ProductName" Header="Product"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
</SfComboBox>
</div>
@code {
private List<CategoryData> Categories = new();
private List<ProductData> FilteredProducts = new();
private int SelectedCategoryID { get; set; }
private async Task OnCategoryChange(ChangeEventArgs<int, CategoryData> args)
{
// Update products based on category
FilteredProducts = await GetProductsByCategory(args.Value);
}
private async Task<List<ProductData>> GetProductsByCategory(int categoryID)
{
return await Http.GetFromJsonAsync<List<ProductData>>($"/api/products?categoryId={categoryID}");
}
}MultiColumn ComboBox with Custom Templates
@using Syncfusion.Blazor.MultiColumnComboBox
<SfMultiColumnComboBox TValue="int" TItem="EmployeeData"
DataSource="@Employees"
TextField="EmployeeName"
ValueField="EmployeeID"
@bind-Value="@SelectedEmployeeID">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="EmployeeID" Header="ID" Width="80px"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="EmployeeName" Header="Name" Width="150px">
<Template>
@{
var employee = context as EmployeeData;
<div style="display: flex; align-items: center; gap: 10px;">
<img src="@employee.ProfileImage" alt="@employee.EmployeeName" style="width: 30px; height: 30px; border-radius: 50%;">
<div>
<strong>@employee.EmployeeName</strong>
<br />
<small>@employee.Department</small>
</div>
</div>
}
</Template>
</MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="Department" Header="Department" Width="120px"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
private int SelectedEmployeeID { get; set; }
private List<EmployeeData> Employees = new();
public class EmployeeData
{
public int EmployeeID { get; set; }
public string EmployeeName { get; set; }
public string Department { get; set; }
public string ProfileImage { get; set; }
}
}---
Examples
Complete Advanced Integration
@page "/advanced-integration"
@using Syncfusion.Blazor.MultiColumnComboBox
@using System.Collections.ObjectModel
<h3>Advanced Order Management</h3>
<div class="row">
<div class="col-md-6">
<h5>Search with Real-Time Filtering</h5>
<SfMultiColumnComboBox TValue="int" TItem="OrderData"
DataSource="@FilteredOrders"
AllowFiltering="true"
Filtering="@OnFilter"
EnableVirtualization="true"
TextField="CustomerName"
ValueField="OrderID"
Placeholder="Search orders...">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="OrderID" Header="Order ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="CustomerName" Header="Customer"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="Status" Header="Status"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
</div>
<div class="col-md-6">
<h5>Cascading Selection</h5>
<SfMultiColumnComboBox TValue="string" TItem="CategoryData"
DataSource="@Categories"
TextField="CategoryID"
ValueField="CategoryID"
@bind-Value="@SelectedCategory"
ValueChange="@OnCategoryChanged">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="CategoryID" Header="Category"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
<SfMultiColumnComboBox TValue="int" TItem="SubcategoryData"
DataSource="@FilteredSubcategories"
TextField="SubcategoryName"
ValueField="SubcategoryID"
Placeholder="Select subcategory">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="SubcategoryID" Header="Subcategory"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="SubcategoryName" Header="Name"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
</div>
</div>
@code {
private List<OrderData> AllOrders = new();
private List<OrderData> FilteredOrders = new();
private List<CategoryData> Categories = new();
private List<SubcategoryData> FilteredSubcategories = new();
private string SelectedCategory { get; set; }
protected override void OnInitialized()
{
// Initialize data
AllOrders = GenerateOrders(1000);
FilteredOrders = AllOrders;
Categories = GenerateCategories();
}
private async Task OnFilter(FilteringEventArgs args)
{
args.PreventDefaultAction = true;
var searchTerm = args.Text.ToLower();
FilteredOrders = AllOrders
.Where(o => o.OrderID.ToString().Contains(searchTerm) ||
o.CustomerName.ToLower().Contains(searchTerm))
.ToList();
}
private async Task OnCategoryChanged(ChangeEventArgs<string, CategoryData> args)
{
FilteredSubcategories = await GetSubcategoriesAsync(args.Value);
}
private async Task<List<SubcategoryData>> GetSubcategoriesAsync(string categoryID)
{
return new List<SubcategoryData>();
}
private List<OrderData> GenerateOrders(int count)
{
return Enumerable.Range(1, count)
.Select(i => new OrderData
{
OrderID = 1000 + i,
CustomerName = $"Customer {i}",
Status = (OrderStatus)(i % 4)
})
.ToList();
}
private List<CategoryData> GenerateCategories()
{
return new() { new CategoryData { CategoryID = "1", CategoryName = "Electronics" } };
}
public class OrderData
{
public int OrderID { get; set; }
public string CustomerName { get; set; }
public OrderStatus Status { get; set; }
}
public class CategoryData
{
public string CategoryID { get; set; }
public string CategoryName { get; set; }
}
public class SubcategoryData
{
public int SubcategoryID { get; set; }
public string SubcategoryName { get; set; }
}
public enum OrderStatus { Pending, Processing, Shipped, Delivered }
}---
Next Steps
- Accessibility: See references/accessibility-localization.md
- Styling: See references/styling-and-appearance.md
- Complete examples: Check parent SKILL.md for guided patterns
Columns and Data Display
Table of Contents
- Column Configuration
- Column Properties
- Text Alignment and Formatting
- Column Templates
- Header Templates
- Grid Settings
- Text Wrapping
- Examples
---
Column Configuration
Basic Column Definition
Define columns using <MultiColumnComboboxColumn> elements inside <MultiColumnComboboxColumns>:
<SfMultiColumnComboBox TValue="int" TItem="ProductData" DataSource="@Products">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="ProductID" Header="ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="ProductName" Header="Product Name"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="Category" Header="Category"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>Key Points:
Fieldmust match property name in data model (case-sensitive)Headerdisplays as column title- Order in markup determines column order
- Each column shows in the popup grid
Multiple Columns
<SfMultiColumnComboBox TValue="string" TItem="OrderData" DataSource="@Orders">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="OrderID" Header="Order" Width="100px"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="CustomerName" Header="Customer" Width="180px"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="OrderDate" Header="Date" Width="120px" Format="MM/dd/yyyy"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="TotalAmount" Header="Total" Width="110px" Format="C2"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="Status" Header="Status" Width="100px"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>---
Column Properties
Width Management
<!-- Fixed width in pixels -->
<MultiColumnComboboxColumn Field="Name" Header="Name" Width="200px"></MultiColumnComboboxColumn>
<!-- Percentage width -->
<MultiColumnComboboxColumn Field="Email" Header="Email" Width="30%"></MultiColumnComboboxColumn>
<!-- Auto width (fills remaining space) -->
<MultiColumnComboboxColumn Field="Description" Header="Desc" Width="auto"></MultiColumnComboboxColumn>Display Formatting
<!-- Currency format -->
<MultiColumnComboboxColumn Field="Price" Header="Price" Format="C2"></MultiColumnComboboxColumn>
<!-- Number format with decimals -->
<MultiColumnComboboxColumn Field="Quantity" Header="Qty" Format="N0"></MultiColumnComboboxColumn>
<!-- Date format -->
<MultiColumnComboboxColumn Field="OrderDate" Header="Date" Format="MM/dd/yyyy"></MultiColumnComboboxColumn>
<!-- Percentage -->
<MultiColumnComboboxColumn Field="Discount" Header="Discount" Format="P1"></MultiColumnComboboxColumn>Common Format Strings:
C2- Currency with 2 decimalsN0- Number with no decimalsN2- Number with 2 decimalsP1- Percentage with 1 decimalMM/dd/yyyy- Date formatHH:mm:ss- Time format
Column Customization
<!-- Custom attributes for column -->
<MultiColumnComboboxColumn Field="ProductID" Header="ID" Width="80px"></MultiColumnComboboxColumn>
<!-- Display boolean as checkbox -->
<MultiColumnComboboxColumn Field="IsActive" Header="Active" DisplayAsCheckBox="true"></MultiColumnComboboxColumn>---
Text Alignment and Formatting
Alignment Options
<!-- Left-aligned (default) -->
<MultiColumnComboboxColumn Field="Name" Header="Name" TextAlign="TextAlign.Left"></MultiColumnComboboxColumn>
<!-- Right-aligned (good for numbers) -->
<MultiColumnComboboxColumn Field="Price" Header="Price" TextAlign="TextAlign.Right"></MultiColumnComboboxColumn>
<!-- Center-aligned -->
<MultiColumnComboboxColumn Field="Status" Header="Status" TextAlign="TextAlign.Center"></MultiColumnComboboxColumn>Best Practices
<!-- Text columns: Left -->
<MultiColumnComboboxColumn Field="ProductName" Header="Product" TextAlign="TextAlign.Left"></MultiColumnComboboxColumn>
<!-- Number columns: Right -->
<MultiColumnComboboxColumn Field="Quantity" Header="Qty" TextAlign="TextAlign.Right" Format="N0"></MultiColumnComboboxColumn>
<!-- Date columns: Center -->
<MultiColumnComboboxColumn Field="OrderDate" Header="Date" TextAlign="TextAlign.Center" Format="MM/dd/yyyy"></MultiColumnComboboxColumn>
<!-- Status/Boolean: Center -->
<MultiColumnComboboxColumn Field="IsActive" Header="Active" TextAlign="TextAlign.Center" DisplayAsCheckBox="true"></MultiColumnComboboxColumn>---
Column Templates
Item Template
Customize how column cells display:
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@Products"
TextField="ProductName"
ValueField="ProductID">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="ProductName" Header="Product">
<Template>
<div class="product-item">
<strong>@((context as ProductData).ProductName)</strong>
</div>
</Template>
</MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="Price" Header="Price" Format="C2"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>Footer Template
Display custom footer in dropdown:
<SfMultiColumnComboBox TValue="int" TItem="OrderData"
DataSource="@Orders"
@bind-Value="@SelectedOrderID">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="OrderID" Header="Order"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="CustomerName" Header="Customer"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
<FooterTemplate>
<div style="padding: 10px;">
Total Orders: @context.Count
</div>
</FooterTemplate>
</SfMultiColumnComboBox>
@code {
private int SelectedOrderID { get; set; }
}Group Template
When grouping is enabled, customize group headers:
<SfMultiColumnComboBox TValue="string" TItem="ProductData"
DataSource="@Products"
GroupByField="Category">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="ProductName" Header="Product"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="Category" Header="Category"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
<GroupTemplate>
<div class="group-header">
<strong>📦 Category: @context</strong>
</div>
</GroupTemplate>
</SfMultiColumnComboBox>---
Header Templates
Custom Column Header
<SfMultiColumnComboBox TValue="int" TItem="ProductData" DataSource="@Products">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="ProductName" Header="Product">
<HeaderTemplate>
<div class="header-template">
<strong>📦 Product Name</strong>
</div>
</HeaderTemplate>
</MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="Price" Header="Price">
<HeaderTemplate>
<div class="header-template">
<strong>💰 Price</strong>
</div>
</HeaderTemplate>
</MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>---
Grid Settings
Row Height
MultiColumnComboBox TValue="int" TItem="ProductData" DataSource="@Products" RowHeight="40"> <MultiColumnComboboxColumns>
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@Products"
RowHeight="40">
<MultiColumnComboboxColumns>
<!-- Columns -->
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>Alternating Rows
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@Products"
EnableAltRow="true">
<MultiColumnComboboxColumns>
<!-- Columns -->
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>Grid Lines
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@Products"
GridLines="GridLine.Both">
<MultiColumnComboboxColumns>
<!-- Columns -->
</MultiColumnComboboxColumns>
</SfMultiColumnridLine.None` - No grid lines
- `GridLine.Horizontal` - Only horizontal
- `GridLine.Vertical` - Only vertical
- `GridLine.Both` - Both horizontal and vertical
---
## Text Wrapping
### Enable Text Wrapping
Text wrapping is controlled at the component level using `EnableTextWrap` property:
<SfMultiColumnComboBox TValue="int" TItem="ProductData" DataSource="@Products" EnableTextWrap="true" TextWrapElement="TextWrapElement.Both"> <MultiColumnComboboxColumns> <MultiColumnComboboxColumn Field="Description" Header="Description" Width="250px"></MultiColumnComboboxColumn> </MultiColumnComboboxColumns> </SfMultiColumnComboBox>
**When to use:**
- Long text content
- Product descriptions
- Comments or notes
- Flexible height columns
---
## Examples
### Complete Multi-Column Example
@page "/employee-selector" @using Syncfusion.Blazor.MultiColumnComboBox
<h3>Employee Selection</h3>
<SfMultiColumnComboBox TValue="int" TItem="EmployeeData" DataSource="@Employees" TextField="FirstName" ValueField="EmployeeID" Placeholder="Select an employee" EnableAltRow="true" GridLines="GridLine.Both"> <MultiColumnComboboxColumns> <MultiColumnComboboxColumn Field="EmployeeID" Header="ID" Width="80px" TextAlign="TextAlign.Center"></MultiColumnComboboxColumn> <MultiColumnComboboxColumn Field="FirstName" Header="First Name" Width="120px"></MultiColumnComboboxColumn> <MultiColumnComboboxColumn Field="LastName" Header="Last Name" Width="120px"></MultiColumnComboboxColumn> <MultiColumnComboboxColumn Field="DepartultiColumnComboBox>
@code { private List<EmployeeData> Employees = new()rivate ComboBoxFieldSettings ComboFields = new ComboBoxFieldSettings { Text = "FirstName", Value = "EmployeeID" };
protected override void OnInitialized() { Employees = new() { new EmployeeData { EmployeeID = 1, FirstName = "John", LastName = "Doe", Department = "Sales", Salary = 50000m, HireDate = new DateTime(2020, 1, 15) }, new EmployeeData { EmployeeID = 2, FirstName = "Jane", LastName = "Smith", Department = "IT", Salary = 60000m, HireDate = new DateTime(2019, 6, 20) }, new EmployeeData { EmployeeID = 3, FirstName = "Bob", LastName = "Johnson", Department = "HR", Salary = 55000m, HireDate = new DateTime(2021, 3, 10) } }; }
public class EmployeeData { public int EmployeeID { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Department { get; set; } public decimal Salary { get; set; } public DateTime HireDate { get; set; } } }
---
## Next Steps
- **Format numbers and dates:** Use Format strings as shown above
- **Handle selection:** See [references/selection-and-values.md](selection-and-values.md)
- **Style columns:** See [references/styling-and-appearance.md](styling-and-appearance.md)
Data Binding
Table of Contents
- Local Data Binding
- Observable Collections
- Complex Data Types
- Web API Binding
- OData Services
- Action Events
- Custom Adaptors
- Offline Mode
- Troubleshooting
---
Local Data Binding
Simple List Binding
Bind directly to a C# List:
@page "/local-binding"
@using Syncfusion.Blazor.MultiColumnComboBox
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@Products"
TextField="ProductName"
ValueField="ProductID"
Placeholder="Select a product">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="ProductID" Header="ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="ProductName" Header="Name"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
private List<ProductData> Products = new();
protected override void OnInitialized()
{
Products = new()
{
new ProductData { ProductID = 1, ProductName = "Laptop" },
new ProductData { ProductID = 2, ProductName = "Mouse" },
new ProductData { ProductID = 3, ProductName = "Keyboard" }
};
}
public class ProductData
{
public int ProductID { get; set; }
public string ProductName { get; set; }
}
}Asynchronous Data Loading
Load data from API or database:
protected override async Task OnInitializedAsync()
{
Products = await FetchProductsFromAPI();
}
private async Task<List<ProductData>> FetchProductsFromAPI()
{
using var http = new HttpClient();
return await http.GetFromJsonAsync<List<ProductData>>("https://api.example.com/products");
}---
Observable Collections
Dynamic Updates
Use ObservableCollection for real-time updates:
@using System.Collections.ObjectModel
<button @onclick="AddProduct">Add Product</button>
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@Products"
TextField="ProductName"
ValueField="ProductID"
Placeholder="Select a product">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="ProductID" Header="ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="ProductName" Header="Name"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
private ObservableCollection<ProductData> Products = new();
protected override void OnInitialized()
{
Products = new ObservableCollection<ProductData>
{
new ProductData { ProductID = 1, ProductName = "Product A" },
new ProductData { ProductID = 2, ProductName = "Product B" }
};
}
private void AddProduct()
{
Products.Add(new ProductData
{
ProductID = Products.Count + 1,
ProductName = $"Product {(char)('C' + Products.Count)}"
});
}
public class ProductData
{
public int ProductID { get; set; }
public string ProductName { get; set; }
}
}Benefits:
- ✓ UI updates automatically when collection changes
- ✓ Add/remove items dynamically
- ✓ No need to reassign DataSource
---
Complex Data Types
Enum Binding
<SfMultiColumnComboBox TValue="OrderStatus" TItem="OrderData"
DataSource="@Orders"
TextField="Status"
ValueField="Status"
Placeholder="Select status">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="OrderID" Header="Order"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="Status" Header="Status"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
private List<OrderData> Orders = new();
public enum OrderStatus
{
Pending,
Processing,
Shipped,
Delivered
}
public class OrderData
{
public int OrderID { get; set; }
public OrderStatus Status { get; set; }
}
protected override void OnInitialized()
{
Orders = new()
{
new OrderData { OrderID = 1001, Status = OrderStatus.Pending },
new OrderData { OrderID = 1002, Status = OrderStatus.Shipped }
};
}
}Value Tuples
@code {
private List<(int Id, string Name, decimal Price)> Products = new();
protected override void OnInitialized()
{
Products = new()
{
(1, "Product A", 99.99m),
(2, "Product B", 149.99m),
(3, "Product C", 199.99m)
};
}
}Dynamic Objects
@code {
private List<dynamic> Products = new();
protected override void OnInitialized()
{
Products = new()
{
new { ProductID = 1, ProductName = "Item A", Category = "Electronics" },
new { ProductID = 2, ProductName = "Item B", Category = "Books" }
};
}
}ExpandoObject
@using System.Dynamic
@code {
private List<ExpandoObject> Products = new();
protected override void OnInitialized()
{
var product1 = new ExpandoObject();
product1.ProductID = 1;
product1.ProductName = "Product A";
product1.Category = "Electronics";
Products.Add(product1);
}
}---
Web API Binding
Using Data Adaptor
@page "/web-api-binding"
@using Syncfusion.Blazor.MultiColumnComboBox
@using Syncfusion.Blazor.Data
<SfMultiColumnComboBox TValue="int" TItem="OrderData"
Query="@GridQuery"
TextField="CustomerName"
ValueField="OrderID"
Placeholder="Select an order">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="OrderID" Header="Order ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="CustomerName" Header="Customer"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="TotalAmount" Header="Amount" Format="C2"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
private Query GridQuery = new Query().From("Orders").Select(new List<string> { "OrderID", "CustomerName", "TotalAmount" });
public class OrderData
{
public int OrderID { get; set; }
public string CustomerName { get; set; }
public decimal TotalAmount { get; set; }
}
}With HttpClient
@inject HttpClient Http
@code {
private List<OrderData> Orders = new();
protected override async Task OnInitializedAsync()
{
try
{
Orders = await Http.GetFromJsonAsync<List<OrderData>>("https://api.example.com/api/orders");
}
catch (Exception ex)
{
// Handle error
Console.WriteLine($"Error loading orders: {ex.Message}");
}
}
public class OrderData
{
public int OrderID { get; set; }
public string CustomerName { get; set; }
public decimal TotalAmount { get; set; }
}
}---
OData Services
OData Binding
@page "/odata-binding"
@using Syncfusion.Blazor.MultiColumnComboBox
@using Syncfusion.Blazor.Data
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
Query="@ODataQuery"
TextField="ProductName"
ValueField="ProductID"
Placeholder="Select a product">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="ProductID" Header="ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="ProductName" Header="Name"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
private Query ODataQuery = new Query()
.From("Products")
.Select(new List<string> { "ProductID", "ProductName", "Category" })
.Take(20);
public class ProductData
{
public int ProductID { get; set; }
public string ProductName { get; set; }
public string Category { get; set; }
}
}Action Events
ActionBegin Event
Fires before data operations:
<SfMultiColumnComboBox TValue="int" TItem="OrderData"
DataSource="@Orders"
OnActionBegin="@OnActionBegin">
<MultiColumnComboboxColumns>
<!-- Columns -->
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
private async Task OnActionBegin(ActionBeginEventArgs args)
{
// args.RequestType = filter, paging, sorting, etc.
// Can be used for pre-processing
Console.WriteLine($"Action: {args.RequestType}");
await Task.CompletedTask;
}
}ActionComplete Event
Fires after an action completes:
<SfMultiColumnComboBox TValue="int" TItem="OrderData"
DataSource="@Orders"
OnActionComplete="@OnActionComplete">
<MultiColumnComboboxColumns>
<!-- Columns -->
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
private async Task OnActionComplete(ActionCompleteEventArgs<OrderData> args)
{
// args.Result = data returned
// args.Count = total record count
Console.WriteLine($"Completed: {args.Count} records");
await Task.CompletedTask;
}
}ActionFailure Event
Fires on error:
<SfMultiColumnComboBox TValue="int" TItem="OrderData"
DataSource="@Orders"
OnActionFailure="@OnActionFailure">
<MultiColumnComboboxColumns>
<!-- Columns -->
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
private async Task OnActionFailure(Exception error)
{
// error = exception details
Console.WriteLine($"Error: {error.Message
Console.WriteLine($"Error: {args.Error}");
await Task.CompletedTask;
}
}---
Custom Adaptors
Implement Custom Adaptor
using Syncfusion.Blazor.Data;
public class CustomAdaptor : DataAdaptor
{
private List<OrderData> Orders = new();
public override async Task<object> Read(DataManagerRequest dm, string key = null)
{
// Load from database or API
var allData = await FetchFromDatabase();
// Apply filtering if needed
if (dm.Where != null && dm.Where.Count > 0)
{
// Filter logic
}
// Apply paging
if (dm.Skip > 0)
allData = allData.Skip(dm.Skip).ToList();
if (dm.Take > 0)
allData = allData.Take(dm.Take).ToList();
return new DataResult()
{
Result = allData,
Count = allData.Count
};
}
private async Task<List<OrderData>> FetchFromDatabase()
{
// Database call logic
return new List<OrderData>();
}
public class OrderData
MultiColumnComboBox TValue="int" TItem="OrderData"
DataManager="@DataManagerInstance">
<MultiColumnComboboxColumns>
<!-- Columns -->
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
private DataManager DataManagerInstance = new DataManager()
{
Adaptor = Adaptors.CustomAdaptor,
AdaptorInstance = typeof(CustomAdaptor)
}
### Use Custom Adaptor
DataManager="@DataManagerInstance"> <MultiColumnComboboxColumns> <!-- Columns --> </MultiColumnComboboxColumns> </SfMultiColumnComboBox>
@code { private DataManager DataManagerInstance = new DataManager() { Adaptor = Adaptors.CustomAdaptor, AdaptorInstance = typeof(CustomAdaptor) }; }
---
## Offline Mode
### Cache Data Locally
Enable offline mode for local caching:
<SfMultiColumnComboBox TValue="int" TItem="ProductData" Query="@GridQuery" TextField="ProductName" ValueField="ProductID" Placeholder="Select product"> <MultiColumnComboboxColumns> <MultiColumnComboboxColumn Field="ProductID" Header="ID"></MultiColumnComboboxColumn> <MultiColumnComboboxColumn Field="ProductName" Header="Product"></MultiColumnComboboxColumn> </MultiColumnComboboxColumns> </SfMultiColumnComboBox>
@code { private Query GridQuery = new Query().From("Products"); }
**Benefits:**
- ✓ Data cached locally
- ✓ Works without internet temporarily
- ✓ Syncs when connection restored
---
ld names match exactly
- ✓ TextField and ValueField are set correctly
**Debug Example:**
<!-- Verify with debug output --> @if (Products == null) { <p>Products list is null</p> } else if (Products.Count == 0) { <p>Products list is empty</p> } else { <SfMultiColumnComboBox TValue="int" TItem="ProductData" DataSource="@Products" TextField="ProductName" ValueField="ProductID"> <MultiColumnComboboxColumns> <!-- Columns --> </MultiColumnComboboxColumns> </SfMultiColumnComboBox> }
### Issue: API Call Not Triggering
**Solution:** Ensure API is configured correctly:
protected override async Task OnInitializedAsync() { try { var response = await Http.GetAsync("https://api.example.com/products"); if (response.IsSuccessStatusCode) MultiColumnComboBox TValue="string" TItem="OrderData" DataSource="@Orders" @bind-Value="@SelectedOrderID"> <MultiColumnComboboxColumns> <!-- Columns --> </MultiColumnComboboxColumns> </SfMultiColumnComboBox>
@code { private int SelectedOrderID { get; set; } // Type mismatch! }
<!-- ✅ CORRECT --> <SfMultiColumnComboBox TValue="int" TItem="OrderData" DataSource="@Orders" @bind-Value="@SelectedOrderID"> <MultiColumnComboboxColumns> <!-- Columns --> </MultiColumnComboboxColumns> </SfMultiColumnComboBox>
@code { private int SelectedOrderID { get; set; } }
**Solution:** Ensure TValue matches the @bind-Value property type.
---
Next Steps
- Filter data: See references/filtering-and-search.md
- Handle selection: See references/selection-and-values.md
- Optimize performance: See references/features-and-settings.md
Features and Settings
Table of Contents
- Paging
- Virtualization
- Grouping
- Popup Settings
- Placeholder and Float Label
- Grid Settings
- Form Validation
- Enabled and Disabled States
- Examples
---
Paging
Enable Paging
Load data in pages instead of all at once:
<SfMultiColumnComboBox TValue="int" TItem="OrderData"
DataSource="@Orders"
AllowPaging="true"
PageSize="10"
TextField="CustomerName"
ValueField="OrderID"
Placeholder="Select an order">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="OrderID" Header="Order ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="CustomerName" Header="Customer"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
private List<OrderData> Orders = new();
// 100+ items, shown 10 per page
}Page Size Settings
<!-- 15 items per page -->
<SfMultiColumnComboBox TValue="int" TItem="OrderData"
DataSource="@Orders"
AllowPaging="true"
PageSize="15">
<MultiColumnComboboxColumns>
<!-- Columns -->
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>Use cases:
- ✓ Large datasets (1000+ records)
- ✓ Remote data with bandwidth concerns
- ✓ Better UX with gradual loading
---
Virtualization
Virtual Scrolling
Render only visible rows for extreme performance:
<SfMultiColumnComboBox TValue="int" TItem="OrderData"
DataSource="@Orders"
EnableVirtualization="true"
TextField="CustomerName"
ValueField="OrderID"
Placeholder="Select an order">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="OrderID" Header="Order ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="CustomerName" Header="Customer"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
private List<OrderData> Orders = new();
// Can handle 10,000+ items smoothly
}Benefits:
- ✓ Handles 10,000+ items smoothly
- ✓ Minimal memory footprint
- ✓ Fast scrolling performance
- ✓ Better than paging for large lists
Combined with Paging
<SfMultiColumnComboBox TValue="int" TItem="OrderData"
DataSource="@Orders"
AllowPaging="true"
PageSize="50"
EnableVirtualization="true">
<MultiColumnComboboxColumns>
<!-- Columns -->
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>---
Grouping
Group by Field
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@Products"
GroupByField="Category"
TextField="ProductName"
ValueField="ProductID"
Placeholder="Select a product">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="ProductID" Header="ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="ProductName" Header="Product"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="Category" Header="Category"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
public class ProductData
{
public int ProductID { get; set; }
public string ProductName { get; set; }
public string Category { get; set; }
}
private List<ProductData> Products = new()
{
new ProductData { ProductID = 1, ProductName = "Laptop", Category = "Electronics" },
new ProductData { ProductID = 2, ProductName = "Mouse", Category = "Electronics" },
new ProductData { ProductID = 3, ProductName = "Desk", Category = "Furniture" },
new ProductData { ProductID = 4, ProductName = "Chair", Category = "Furniture" }
};
}Note: GroupByField accepts a single string field name for grouping. For complex grouping scenarios, consider using Query with remote data.
---
Popup Settings
Popup Position and Size
<SfMultiColumnComboBox TValue="int" TItem="OrderData"
DataSource="@Orders"
PopupHeight="400px"
PopupWidth="600px">
<MultiColumnComboboxColumns>
<!-- Columns -->
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>Column Resizing
<SfMultiColumnComboBox TValue="int" TItem="OrderData"
DataSource="@Orders"
TextField="CustomerName"
ValueField="OrderID"
AllowColumnResizing="true"
PopupHeight="300px"
PopupWidth="500px">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="OrderID" Header="Order ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="CustomerName" Header="Customer"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>Behavior: User can drag column borders to resize columns in the popup.
Popup Events
<SfMultiColumnComboBox TValue="int" TItem="OrderData"
DataSource="@Orders"
PopupOpening="@OnPopupOpening"
PopupClosing="@OnPopupClosing">
<MultiColumnComboboxColumns>
<!-- Columns -->
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
private async Task OnPopupOpening(PopupOpeningEventArgs args)
{
Console.WriteLine("Popup opening");
await Task.CompletedTask;
}
private async Task OnPopupClosing(PopupClosing
}EventArgs args)
{
Console.WriteLine("Popup closing");
await Task.CompletedTask;
}---
Placeholder and Float Label
MultiColumnComboBox TValue="int" TItem="ProductData" DataSource="@Products" Placeholder="Choose a product..."> <MultiColumnComboboxColumns> <!-- Columns --> </MultiColumnComboboxColumns> </SfMultiColumnComboBox>
### Float Label
<SfMultiColumnComboBox TValue="int" TItem="ProductData" DataSource="@Products" FloatLabelType="FloatLabelType.Auto" Placeholder="Product Name"> <MultiColumnComboboxColumns> <!-- Columns --> </MultiColumnComboboxColumns> </SfMultiColumn DataSource="@Products" FloatLabelType="FloatLabelType.Auto" Placeholder="Product Name"> <!-- Columns --> </SfComboBox>
**FloatLabelType Options:**
- `Auto` - Floats on focus or input
- `Always` - Always floats
- `Never` - Never floats
### Custom Placeholder Color
yle>
.custom-placeholder .e-input::placeholder {
color: #888;
}
</style>
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@Products"
CssClass="custom-placeholder"
Placeholder="Select product...">
<MultiColumnComboboxColumns>
<!-- Columns -->
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>---
Grid Settings
Row Height
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@Products"
RowHeight="35">
<MultiColumnComboboxColumns>
<!-- Columns -->
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>Alternating Row Colors
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@Products"
EnableAltRow="true">
<MultiColumnComboboxColumns>
<!-- Columns -->
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>Grid Lines
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@Products"
GridLines="GridLine.Both">
<MultiColumnComboboxColumns>
<!-- Columns -->
</MultiColumnComboboxColumns>
</SfMultiColumn GridLines="GridLine.Both">
<!-- Columns -->
</SfComboBox>---
Form Validation
Bind to EditForm
<EditForm Model="@OrderModel" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<div class="form-group">
<label>Order:</label>
<SfMultiColumnComboBox TValue="int" TItem="OrderData"
DataSource="@Orders"
@bind-Value="@OrderModel.SelectedOrderID">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="OrderID" Header="Order ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="CustomerName" Header="Customer"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
<ValidationMessage For="@(() => OrderModel.SelectedOrderID)" />
</div>
<button type="submit">Submit</button>
</EditForm>
@code {
private OrderModel OrderModel = new();
private List<OrderData> Orders = new();
public class OrderModel
{
[Required(ErrorMessage = "Order selection is required")]
public int SelectedOrderID { get; set; }
}
public class OrderData
{
public int OrderID { get; set; }
public string CustomerName { get; set; }
}
private async Task HandleValidSubmit()
{
Console.WriteLine($"Form submitted with Order: {OrderModel.SelectedOrderID}");
await Task.CompletedTask;
}
protected override void OnInitialized()
{
Orders = new()
{
new OrderData { OrderID = 1001, CustomerName = "Alice" },
new OrderData { OrderID = 1002, CustomerName = "Bob" }
};
}
}Custom Validation
public class OrderModel
{
[Required]
[Range(1000, 9999, ErrorMessage = "Invalid order number")]
public int SelectedOrderID { get; set; }
}---
Enabled and Disabled States
Disable ComboBox
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@Products"
Disabled="true"
Placeholder="This is disabled">
<MultiColumnComboboxColumns>
<!-- Columns -->
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>Conditionally Enable/Disable
MultiColumnComboBox TValue="int" TItem="ProductData" DataSource="@Products" Disabled="@IsDisabled"
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@Products"
Disabled="@IsDisabled"
@bind-Value="@SelectedProductID">
<MultiColumnComboboxColumns>
<!-- Columns -->
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
<button @onclick="@(() => IsDisabled = !IsDisabled)">Toggle Enable</button>
@code {
private bool IsDisabled = false;
private int SelectedProductID { get; set; }
}ReadOnly Mode
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@Products"
ReadOnly="true"
@bind-Value="@SelectedProductID">
<MultiColumnComboboxColumns>
<!-- Columns -->
</MultiColumnComboboxColumns>
</SfMultiColumn
## ExamplesMultiColumnComboBox
<h3>Advanced Order Selection</h3>
### Complete MultiColumn ComboBox Example
@page "/advanced-combobox" <div class="form-group mb-3"> <label>Search Options:</label> <div> <label> <input type="checkbox" @bind="ShowPaging" /> Enable Paging (10 items/page) </label> <label> <input type="checkbox" @bind="ShowVirtualization" /> Enable Virtualization </label> <label> <input type="checkbox" @bind="ShowGrouping" /> Group by Status </label> </div> </div>
<SfMultiColumnComboBox TValue="int" TItem="OrderData" DataSource="@FilteredOrders" AllowPaging="@ShowPaging" PageSize="10" EnableVirtualization="@ShowVirtualization" GroupByField="@(ShowGrouping ? \"Status\" : null)" AllowFiltering="true" FloatLabelType="FloatLabelType.Auto" Placeholder="Select an order" EnableAltRow="true" GridLines="GridLine.Both" PopupHeight="400px" TextField="CustomerName" ValueField="OrderID" @bind-Value="@SelectedOrderID"> <MultiColumnComboboxColumns> <MultiColumnComboboxColumn Field="OrderID" Header="Order ID" Width="100px"></MultiColumnComboboxColumn> <MultiC<ComboBoxColumn Field="OrderID" Header="Order ID" Width="100px"></ComboBoxColumn> <ComboBoxColumn Field="CustomerName" Header="Customer" Width="150px"></ComboBoxColumn> <ComboBoxColumn Field="Status" Header="Status" Width="100px"></ComboBoxColumn> <ComboBoxColumn Field="TotalAmount" Header="Amount" Width="120px" Format="C2" TextAlign="TextAlign.Right"></ComboBoxColumn> </SfComboBox>
<p class="mt-3">Selected Order ID: <strong>@SelectedOrderID</strong></p>
@code { private List<OrderData> FilteredOrders = new(); private int SelectedOrderID { get; set; } private bool ShowPaging = false; private bool ShowVirtualization = false; private bool ShowGrouping = false;
protected override void OnInitialized() { // Generate sample data var orders = new List<OrderData>(); for (int i = 1; i <= 100; i++) { orders.Add(new OrderData { OrderID = 1000 + i, CustomerName = $"Customer {i}", Status = (OrderStatus)(i % 4), TotalAmount = (decimal)(50 + i * 1.5) }); } FilteredOrders = orders; }
public enum OrderStatus { Pending, Processing, Shipped, Delivered }
public class OrderData { public int OrderID { get; set; } public string CustomerName { get; set; } public OrderStatus Status { get; set; } public decimal TotalAmount { get; set; } } }
---
## Next Steps
- **Customize styling:** See [references/styling-and-appearance.md](styling-and-appearance.md)
- **Accessibility:** See [references/accessibility-localization.md](accessibility-localization.md)
- **Advanced integration:** See [references/advanced-patterns.md](advanced-patterns.md)
Filtering and Search
Table of Contents
- Enable Filtering
- Filter Types
- Case-Sensitive Filtering
- Custom Filtering
- Multi-Column Filtering
- Filter Length and Debounce
- Remote Filtering
- Filter Events
- Examples
---
Enable Filtering
Basic Filtering
Enable search/filter on the ComboBox:
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@Products"
AllowFiltering="true"
TextField="ProductName"
ValueField="ProductID"
Placeholder="Search products...">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="ProductID" Header="ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="ProductName" Header="Product"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
private List<ProductData> Products = new();
// Data initialization...
}What happens:
- Input box appears above dropdown
- User types to filter results
- Dropdown shows matching items only
- Default filter: contains (case-insensitive)
---
Filter Types
StartsWith
Match from beginning of text:
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@Products"
AllowFiltering="true"
FilterType="FilterType.StartsWith"
Placeholder="Search...">
<MultiColumnComboboxColumns>
<!-- Columns -->
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>Example: Typing "lap" matches "laptop" but not "laptop sleeve"
Contains
Match anywhere in text (default):
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@Products"
AllowFiltering="true"
FilterType="FilterType.Contains"
Placeholder="Search...">
<MultiColumnComboboxColumns>
<!-- Columns -->
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>Example: Typing "top" matches both "laptop" and "desktop"
EndsWith
Match at end of text:
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@Products"
AllowFiltering="true"
FilterType="FilterType.EndsWith"
TextField="ProductName"
ValueField="ProductID"
Placeholder="Search...">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="ProductID" Header="ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="ProductName" Header="Product"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>Example: Typing "top" matches "laptop" but not "topic"
---
Case-Sensitive Filtering
Default: Case-Insensitive
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@Products"
AllowFiltering="true"
TextField="ProductName"
ValueField="ProductID"
Placeholder="Search (case-insensitive)...">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="ProductID" Header="ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="ProductName" Header="Product"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>Behavior: "LAPTOP", "laptop", "LaPtOp" all match
Enable Case-Sensitive
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@Products"
AllowFiltering="true"
IgnoreCase="false"
TextField="ProductName"
ValueField="ProductID"
Placeholder="Search (case-sensitive)...">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="ProductID" Header="ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="ProductName" Header="Product"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>Behavior: Only exact case matches. "laptop" ≠ "LAPTOP"
---
Custom Filtering
Filter by Specific Field
<SfMultiColumnComboBox TValue="int" TItem="EmployeeData"
DataSource="@Employees"
AllowFiltering="true"
FilterType="FilterType.StartsWith"
TextField="FullName"
ValueField="EmployeeID"
Placeholder="Search by name or email">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="EmployeeID" Header="ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="FullName" Header="Name"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="Email" Header="Email"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>Multi-Column Search
Filter across multiple columns:
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@FilteredProducts"
AllowFiltering="true"
FilterType="FilterType.Contains"
Filtering="@OnFilter"
TextField="ProductName"
ValueField="ProductID"
Placeholder="Search by name or category...">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="ProductID" Header="ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="ProductName" Header="Product"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="Category" Header="Category"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
private List<ProductData> AllProducts = new();
private List<ProductData> FilteredProducts = new();
private async Task OnFilter(FilteringEventArgs args)
{
args.PreventDefaultAction = true;
string searchTerm = args.Text.ToLower();
// Filter on multiple columns
FilteredProducts = AllProducts
.Where(p =>
p.ProductName.ToLower().Contains(searchTerm) ||
p.Category.ToLower().Contains(searchTerm) ||
p.ProductID.ToString().Contains(searchTerm)
)
.ToList();
// Notify component of filtered data
await Task.CompletedTask;
}
protected override void OnInitialized()
{
AllProducts = new()
{
new ProductData { ProductID = 1, ProductName = "Laptop", Category = "Electronics" },
new ProductData { ProductID = 2, ProductName = "Mouse Pad", Category = "Accessories" },
new ProductData { ProductID = 3, ProductName = "Keyboard", Category = "Electronics" }
};
FilteredProducts = AllProducts;
}
public class ProductData
{
public int ProductID { get; set; }
public string ProductName { get; set; }
public string Category { get; set; }
}
}Global Filtering
Enable search filtering across the component:
<SfMultiColumnComboBox TValue="int" TItem="OrderData"
DataSource="@Orders"
AllowFiltering="true"
TextField="CustomerName"
ValueField="OrderID">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="OrderID" Header="Order"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="CustomerName" Header="Customer"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="Amount" Header="Amount"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>Result: Component filters across all displayed data.
---
Filter Length and Debounce (Delay)
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@Products"
AllowFiltering="true"
DebounceDelay="500"
Placeholder="Search products...">
<MultiColumnComboboxColumns>
<!-- Columns -->
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>.Purpose: Reduces filtering calls while user is still typing
---
Remote Filtering
Filter from Web API
@page "/remote-filter"
@using Syncfusion.Blazor.DropDowns
@using Syncfusion.Blazor.Data
MultiColumnComboBox
@using Syncfusion.Blazor.Data
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
QuMultiColumnComboBox
@using Syncfusion.Blazor.Data
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
Query="@DataQuery"
AllowFiltering="true"
Filtering="@OnRemoteFilter"
TextField="ProductName"
ValueField="ProductID"
Placeholder="Search products...">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="ProductID" Header="ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="ProductName" Header="Product"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@cod
// Modify query to filter on server
DataQuery = new Query()
.From("products")
.Where("ProductName", "contains", args.Text);
await Task.CompletedTask;
}
public class ProductData
{
public int ProductID { get; set; }
public string ProductName { get; set; }
}
}---
Filter Events
Filtering Event
Fires when user types in filter box: MultiColumnComboBox TValue="int" TItem="ProductData" DataSource="@Products" AllowFiltering="true" Filtering="@OnFiltering"> <MultiColumnComboboxColumns> <!-- Columns --> </MultiColumnComboboxColumns> </SfMultiColumn Filtering="@OnFiltering"> <!-- Columns -->
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@Products"
AllowFiltering="true"
Filtering="@OnFiltering">
<MultiColumnComboboxColumns>
<!-- Columns -->
</MultiColumnComboboxColumns>
</SfMultiColumn
Console.WriteLine($"User typed: {args.Text}");
if (args.Text.Length < 2)
{
args.PreventDefaultAction = true; // Don't show results yet
}
await Task.CompletedTask;
}
}---
Examples
Complete Filtering Setup
@page "/filter-example"
@using Syncfusion.Blazor.MultiColumnComboBox
<h3>Order Filter Example</h3>
<div class="form-group">
<label>Filter Options:</label>
<select @onchange="@((ChangeEventArgs e) => ChangeFilterType(e.Value.ToString()))" class="form-control">
<option value="Contains">Contains</option>
<option value="StartsWith">Starts With</option>
<option value="EndsWith">Ends With</option>
</select>
</div>
<SfMultiColumnComboBox TValue="int" TItem="OrderData"
DataSource="@Orders"
AllowFiltering="true"
FilterType="@CurrentFilterType"
TextField="CustomerName"
ValueField="OrderID"
Placeholder="Search orders by ID or customer name...">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="OrderID" Header="Order ID" Width="100px"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="CustomerName" Header="Customer" Width="200px"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="OrderDate" Header="Date" Width="120px" Format="MM/dd/yyyy"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
private List<OrderData> Orders = new();
private FilterType CurrentFilterType = FilterType.Contains;
protected override void OnInitialized()
{
Orders = new()
{
new OrderData { OrderID = 1001, CustomerName = "Alice Johnson", OrderDate = new DateTime(2024, 1, 15) },
new OrderData { OrderID = 1002, CustomerName = "Bob Smith", OrderDate = new DateTime(2024, 1, 20) },
new OrderData { OrderID = 1003, CustomerName = "Carol White", OrderDate = new DateTime(2024, 1, 25) },
new OrderData { OrderID = 1004, CustomerName = "David Brown", OrderDate = new DateTime(2024, 2, 5) }
};
}
private void ChangeFilterType(string filterType)
{
CurrentFilterType = (FilterType)Enum.Parse(typeof(FilterType), filterType);
}
public class OrderData
{
public int OrderID { get; set; }
public string CustomerName { get; set; }
public DateTime OrderDate { get; set; }
}
}---
Next Steps
- Handle selection: See references/selection-and-values.md
- Optimize performance: See references/features-and-settings.md
- Customize styling: See references/styling-and-appearance.md
Getting Started with MultiColumn ComboBox
Table of Contents
---
Installation
The MultiColumn ComboBox is part of the Syncfusion Blazor package. Install it via NuGet:
dotnet add package Syncfusion.Blazor.MultiColumnComboBoxRegister in App.razor or _Host.cshtml
Add the Syncfusion styles and scripts:
<!-- In Head -->
<link href="_content/Syncfusion.Blazor.Themes/bootstrap5.css" rel="stylesheet" />
<!-- In Body (before closing tag) -->
<script src="_framework/blazor.web.js"></script>
<script src="_content/Syncfusion.Blazor.Core/scripts/syncfusion-blazor.min.js"></script>Add NuGet Package to .csproj
<ItemGroup>
<PackageReference Include="Syncfusion.Blazor.MultiColumnComboBox" Version="latest" />
</ItemGroup>---
Basic Setup
Step 1: Add Using Statement
@using Syncfusion.Blazor.MultiColumnComboBox
@using Syncfusion.Blazor.DataStep 2: Define Your Data Model
public class ProductData
{
public int ProductID { get; set; }
public string ProductName { get; set; }
public string Category { get; set; }
public decimal Price { get; set; }
}Step 3: Prepare Data in OnInitialized
@code {
private List<ProductData> Products = new();
protected override void OnInitialized()
{
Products = new()
{
new ProductData { ProductID = 1, ProductName = "Laptop", Category = "Electronics", Price = 999.99m },
new ProductData { ProductID = 2, ProductName = "Mouse", Category = "Electronics", Price = 29.99m },
new ProductData { ProductID = 3, ProductName = "Keyboard", Category = "Electronics", Price = 79.99m }
};
}
}---
First MultiColumn ComboBox
Minimal Example
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@Products"
TextField="ProductName"
ValueField="ProductID"
Placeholder="Select a product">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="ProductID" Header="ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="ProductName" Header="Product"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>What's happening:
TValue="int"- Selected value type (ProductID)TItem="ProductData"- Data model typeDataSource="@Products"- Binds list of productsTextField- Field to display in inputValueField- Field to use as valuePlaceholder- Helper text before selectionMultiColumnComboboxColumn- Defines visible columns
Multi-Column Display
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@Products"
ValueField="ProductID"
TextField="ProductName"
Placeholder="Pick a product">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="ProductName" Header="Product Name" Width="200px"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="Category" Header="Category" Width="150px"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="Price" Header="Price" Width="100px" Format="C2"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>---
Adding Columns
Column Syntax
<MultiColumnComboboxColumn Field="PropertyName"
Header="Display Header"
Width="150px"
Format="C2"
TextAlign="TextAlign.Right">
</MultiColumnComboboxColumn>| Property | Purpose |
|---|---|
Field | Binds to data property |
Header | Column header text |
Width | Column width (px, %, auto) |
Format | Format string (C2=currency, N2=number) |
TextAlign | Text alignment (Left, Right, Center) |
Multi-Column Example
<SfMultiColumnComboBox TValue="string" TItem="EmployeeData"
DataSource="@Employees"
TextField="Name"
ValueField="EmployeeID"
Placeholder="Select employee">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="EmployeeID" Header="ID" Width="80px"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="Name" Header="Name" Width="150px"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="Department" Header="Dept" Width="120px"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="Salary" Header="Salary" Width="110px" Format="C0"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>---
Binding Data
Local Data Binding
Direct bind with C# List:
@code {
private List<ProductData> Products = new();
protected override void OnInitialized()
{
Products = new()
{
new ProductData { ProductID = 1, ProductName = "Item A", Category = "Category 1" },
new ProductData { ProductID = 2, ProductName = "Item B", Category = "Category 2" }
};
}
}Observable Collection Binding
Auto-updates when collection changes:
@using System.Collections.ObjectModel
@code {
private ObservableCollection<ProductData> Products = new();
protected override void OnInitialized()
{
Products = new ObservableCollection<ProductData>
{
new ProductData { ProductID = 1, ProductName = "Item A", Category = "Cat 1" },
new ProductData { ProductID = 2, ProductName = "Item B", Category = "Cat 2" }
};
}
private void AddProduct()
{
Products.Add(new ProductData { ProductID = 3, ProductName = "Item C", Category = "Cat 3" });
}
}
Map data fields using TextField and ValueField properties:
<SfMultiColumnComboBox TValue="int" TItem="ProductData" DataSource="@Products" TextField="ProductName" ValueField="ProductID"> <MultiColumnComboboxColumns> <!-- Columns --> </MultiColumnComboboxColumns> </SfMultiColumnComboBox>
@code { // TextField = "ProductName" - Display text in input // ValueField = "ProductID" - Value to bind }
---
## Common Issues
### Issue: MultiColumnComboboxColumn elements don't show up.
**Solution:** Ensure you're using the correct namespace and component hierarchy:
@using Syncfusion.Blazor.MultiColumnComboBox
<SfMultiColumnComboBox ...> <MultiColumnComboboxColumns> <MultiColumnComboboxColumn Field="..." Header="..."></MultiColumnComboboxColumn> </MultiColumnComboboxColumns> </SfMultiColumnComboBox>
### Issue: No Data Showing
**Problem:** DataSource is empty or null.
**Checklist:**
- ✓ Data initialized in `OnInitialized()` or property setter
- ✓ List is not null
- ✓ `Field` property names match your data model exactly (case-sensitive)
- ✓ `TextField` and `ValueField` are set correctly
- ✓ Check browser console for errors
**Example:**protected override void OnInitialized() { // Populate data here, not in component parameters Products = LoadProducts(); }
<!-- Verify with debug output -->
@if (Products == null)
{
<p>Products list is null</p>
}
else if (Products.Count == 0)
{
<p>Products list is empty</p>
}
else
{
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@Products">
<MultiColumnComboboxColumns>
<!-- Columns -->
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
}Issue: Selected Value Not Binding
Problem: @bind-Value doesn't update selected item.
Solution: Use proper two-way binding:
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@Products"
@bind-Value="@SelectedProductID">
<MultiColumnComboboxColumns>
<!-- Columns -->
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
private int SelectedProductID { get; set; }
}Issue: Styling Issues
Problem: Component looks unstyled or broken layout.
Solution: Verify theme CSS is loaded in _Host.cshtml or App.razor.
---
Next Steps
- Filter data: See references/filtering-and-search.md
- Customize appearance: See references/styling-and-appearance.md
- Handle selection: See references/selection-and-values.md
Selection and Value Binding
Table of Contents
- Basic Value Binding
- Two-Way Binding
- Selection Change Event
- Complex Object Binding
- Tuple Binding
- Custom Values
- Enum Binding
- Examples
---
Basic Value Binding
One-Way Binding (Read-Only)
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@Products"
Value="@SelectedProductID"
TextField="ProductName"
ValueField="ProductID">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="ProductID" Header="ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="ProductName" Header="Product"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
private int SelectedProductID = 1; // Initial value
private List<ProductData> Products = new();
}Use case: Display selected value but prevent user changes
---
Two-Way Binding
@bind-Value Syntax
Automatically sync selected value with property:
<p>Selected Product ID: @SelectedProductID</p>
<SfMultiColumnComboBox TValue="int" TItem="ProductData"
DataSource="@Products"
@bind-Value="@SelectedProductID"
TextField="ProductName"
ValueField="ProductID"
Placeholder="Select a product">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="ProductID" Header="ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="ProductName" Header="Product"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
<button @onclick="ShowSelected">Show Selected Value</button>
@code {
private int SelectedProductID { get; set; }
private List<ProductData> Products = new();
private void ShowSelected()
{
Console.WriteLine($"Selected: {SelectedProductID}");
}
protected override void OnInitialized()
{
Products = new()
{
new ProductData { ProductID = 1, ProductName = "Laptop" },
new ProductData { ProductID = 2, ProductName = "Mouse" }
};
}
public class ProductData
{
public int ProductID { get; set; }
public string ProductName { get; set; }
}
}Benefits:
- ✓ Value updates in real-time
- ✓ Component reflects model state
- ✓ Easy to sync with forms
Programmatic Updates
private int SelectedProductID { get; set; }
private async Task SelectFirstProduct()
{
SelectedProductID = Products.First().ProductID;
await Task.CompletedTask;
}
private void ClearSelection()
{
SelectedProductID = 0;
}---
Selection Change Event
ValueChange Event
Fires when user selects an item:
<SfMultiColumnComboBox TValue="int" TItem="OrderData"
DataSource="@Orders"
ValueChange="@OnValueChange"
TextField="CustomerName"
ValueField="OrderID">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="OrderID" Header="Order ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="CustomerName" Header="Customer"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
<div>@ResultMessage</div>
@code {
private List<OrderData> Orders = new();
private string ResultMessage = "";
private async Task OnValueChange(ValueChangeEventArgs<int, OrderData> args)
{
// args.Value = selected value (OrderID)
// args.ItemData = full selected object
// args.IsInteracted = user action or programmatic
if (args.ItemData != null)
{
ResultMessage = $"Selected: Order #{args.ItemData.OrderID} - {args.ItemData.CustomerName}";
}
await Task.CompletedTask;
}
}MultiColumnComboBox TValue="int" TItem="ProductData" DataSource="@Products" ValueChanged="@OnValueChanged"> <MultiColumnComboboxColumns> <!-- Columns --> </MultiColumnComboboxColumns> </SfMultiColumnomboBox TValue="int" TItem="ProductData" DataSource="@Products" ValueChanged="@OnValueChanged"> <!-- Columns --> </SfComboBox>
@code { private async Task OnValueChanged(int value) { // Fire after selection complete Console.WriteLine($"New value: {value}"); await Task.CompletedTask; } }
---
## Complex Object Binding
### Bind Full Object (Not Just ID)
MultiColumnComboBox TValue="int" TItem="OrderData"
DataSource="@Orders"
TextField="CustomerName"
ValueField="OrderID"
@bind-Value="@SelectedOrderID"
ValueChange="@OnOrderSelected">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="OrderID" Header="Order ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="CustomerName" Header="Customer"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="TotalAmount" Header="Amount"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
<div>
@if (SelectedOrder != null)
{
<p>Selected Order: @SelectedOrder.OrderID - @SelectedOrder.CustomerName ($@SelectedOrder.TotalAmount)</p>
}
</div>
@code {
private List<OrderData> Orders = new();
private int SelectedOrderID { get; set; }
private OrderData SelectedOrder { get; set; }
private void OnOrderSelected(ValueChangeEventArgs<int, OrderData> args)
{
SelectedOrder = args.ItemData;
private List<OrderData> Orders = new();
private OrderData SelectedOrder { get; set; }
public class OrderData
{
public int OrderID { get; set; }
public string CustomerName { get; set; }
public decimal TotalAmount { get; set; }
}
}Custom Value Types
<SfMultiColumnComboBox TValue="int" TItem="ProductInfo"
DataSource="@Products"
TextField="Name"
ValueField="Id"
@bind-Value="@SelectedProductId">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="Id" Header="ID"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="Name" Header="Name"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="Price" Header="Price" Format="C2"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
private int SelectedProductId { get; set; }
private List<ProductInfo> Products = new();
public class ProductInfo
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
ecimal Price)>
{
MultiColumnComboBox TValue="string" TItem="TagData"
DataSource="@Tags"
AllowCustom="true"
@bind-Value="@SelectedTag"
TextField="TagName"
ValueField="TagName"
Placeholder="Select or enter a tag">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="TagName" Header="Tag"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumn
@code {
private (int, string) SelectedTuple { get; set; }
}---
Custom Values
Allow User to Enter Custom Values
<SfMultiColumnComboBox TValue="string" TItem="TagData"
DataSource="@Tags"
AllowCustom="true"
@bind-Value="@SelectedTag"
TextField="TagName"
ValueField="TagName"
Placeholder="Select or enter a tag">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="TagName" Header="Tag"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
<p>Selected: @SelectedTag</p>
@code {
private List<TagData> Tags = new();
private string SelectedTag { get; set; }
protected override void OnInitialized()
{
Tags = new()
{
new TagData { TagName = "Urgent" },
new TagData { TagName = "Important" },
new TagData { TagName = "Follow-up" }
};
}
public class TagData
{
public string TagName { get; set; }
}
}---
Enum Binding
Bind to Enum Values
<SfMultiColumnComboBox TValue="int" TItem="OrderData"
DataSource="@Orders"
TextField="Status"
ValueField="OrderID"
@bind-Value="@SelectedOrderID">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="OrderID" Header="Order"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="Status" Header="Status"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
@code {
public enum OrderStatus
{
Pending,
Processing,
Shipped,
Delivered,
Cancelled
}
private int SelectedOrderID { get; set; }
public class OrderData
{
public int OrderID { get; set; }
public OrderStatus Status { get; set; }
}
private OrderStatus SelectedStatus { get; set; }
private List<OrderData> Orders = new();
protected override void OnInitialized()
{
Orders = new()
{
new OrderData { OrderID = 1001, Status = OrderStatus.Pending },
new OrderData { OrderID = 1002, Status = OrderStatus.Shipped }
};
}
}---
Examples
Complete Selection Example
@page "/employee-selection"
@using Syncfusion.Blazor.MultiColumnComboBox
<h3>Employee Selection with Details</h3>
<div class="form-group">
<label>Select an Employee:</label>
<SfMultiColumnComboBox TValue="int" TItem="EmployeeData"
DataSource="@Employees"
TextField="FullName"
ValueField="EmployeeID"
@bind-Value="@SelectedEmployeeID"
ValueChange="@OnEmployeeSelected">
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="EmployeeID" Header="ID" Width="70px"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="FullName" Header="Name" Width="150px"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="Department" Header="Department" Width="130px"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="Salary" Header="Salary" Width="100px" Format="C0" TextAlign="TextAlign.Right"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
</div>
@if (SelectedEmployee != null)
{
<div class="alert alert-info mt-3">
<h5>Selected Employee Details</h5>
<p><strong>Name:</strong> @SelectedEmployee.FullName</p>
<p><strong>ID:</strong> @SelectedEmployee.EmployeeID</p>
<p><strong>Department:</strong> @SelectedEmployee.Department</p>
<p><strong>Salary:</strong> @SelectedEmployee.Salary.ToString("C")</p>
<p><strong>Email:</strong> @SelectedEmployee.Email</p>
</div>
}
@code {
private List<EmployeeData> Employees = new();
private int SelectedEmployeeID { get; set; }
private EmployeeData SelectedEmployee { get; set; }
private async Task OnEmployeeSelected(ValueChangeEventArgs<int, EmployeeData> args)
{
SelectedEmployee = args.ItemData;
Console.WriteLine($"Employee selected: {SelectedEmployee?.FullName}");
// Trigger any additional actions (API calls, etc.)
await Task.CompletedTask;
}
protected override void OnInitialized()
{
Employees = new()
{
new EmployeeData
{
EmployeeID = 1,
FullName = "John Doe",
Department = "Engineering",
Salary = 75000m,
Email = "john.doe@company.com"
},
new EmployeeData
{
EmployeeID = 2,
FullName = "Jane Smith",
Department = "Sales",
Salary = 65000m,
Email = "jane.smith@company.com"
},
new EmployeeData
{
EmployeeID = 3,
FullName = "Bob Johnson",
Department = "HR",
Salary = 60000m,
Email = "bob.johnson@company.com"
}
};
}
public class EmployeeData
{
Custom Value Handling
<SfMultiColumnComboBox TValue="string" TItem="CategoryData" DataSource="@Categories" AllowCustom="true" TextField="CategoryName" ValueField="CategoryName" public int EmployeeID { get; set; } public string FullName { get; set; } public string Department { get; set; } public decimal Salary { get; set; } public string Email { get; set; } } }
### Custom Value Handling
<SfMultiColumnComboBox TValue="string" TItem="CategoryData" DataSource="@Categories" AllowCustom="true" TextField="CategoryName" ValueField="CategoryName" @bind-Value="@SelectedCategory"> <MultiColumnComboboxColumns> <MultiColumnComboboxColumn Field="CategoryName" Header="Category"></MultiColumnComboboxColumn> </MultiColumnComboboxColumns> </SfMultiColumnComboBox>
@code { private string SelectedCategory { get; set; }
---
Next Steps
- Validate selection: See references/features-and-settings.md
- Handle form submission: Integrate with EditForm in references/features-and-settings.md
- Customize display: See references/styling-and-appearance.md