In this example, we build a reusable Blazor component using Syncfusion’s SfMultiSelect that supports:
Dynamic option filtering based on a Picklist type (e.g., Color, Unit)
Two-way data binding with a parent component
Internal state management to avoid unnecessary updates
Why This Pattern?
Often in enterprise forms, you need a dynamic dropdown that updates based on a type and preselects values passed from a parent. This setup ensures:
Clean encapsulation
Correct @bind support
Lightweight rendering
✅ Component Markup
<SfMultiSelect TValue="List<PicklistSetDto>"
TItem="PicklistSetDto"
Placeholder="@Label"
DataSource="@Options"
@bind-Value="InternalSelectedValues"
Mode="VisualMode.Box"
AllowFiltering="true"
FilterType="FilterType.Contains"
PopupHeight="300px">
<MultiSelectFieldSettings Text="Text" Value="Value" />
</SfMultiSelect>
Component Logic
@code {
[Parameter]
public string Label { get; set; } = "Select Options";
[Parameter]
public Picklist Name { get; set; }
[Parameter]
public IEnumerable<PicklistSetDto> SelectedValues { get; set; } = new List<PicklistSetDto>();
[Parameter]
public EventCallback<IEnumerable<PicklistSetDto>> SelectedValuesChanged { get; set; }
protected List<PicklistSetDto> Options = new();
private List<PicklistSetDto> _internalSelectedValues = new();
private List<PicklistSetDto> InternalSelectedValues
{
get => _internalSelectedValues;
set
{
if (!_internalSelectedValues.SequenceEqual(value ?? new()))
{
_internalSelectedValues = value ?? new();
SelectedValuesChanged.InvokeAsync(_internalSelectedValues);
}
}
}
protected override async Task OnInitializedAsync()
{
Options = await Task.FromResult(PicklistService.DataSource
.Where(x => x.Name == Name)
.ToList());
}
public override async Task SetParametersAsync(ParameterView parameters)
{
await base.SetParametersAsync(parameters);
InternalSelectedValues = Options
.Where(x => SelectedValues.Any(s => s.Value == x.Value))
.ToList();
}
}

Example Usage in Parent Component
<PicklistMultiSelect Label="Select Colors"
Name="Picklist.Color"
SelectedValues="@colorData"
SelectedValuesChanged="OnColorChanged" />
private List<PicklistSetDto> colorData = new();
private void OnColorChanged(IEnumerable<PicklistSetDto> values)
{
colorData = values.ToList();
}
To efficiently handle large datasets in Syncfusion’s SfMultiSelect in Blazor, you should avoid loading the entire dataset into memory and instead use server-side filtering and paging. Here's how to implement it:
<SfMultiSelect TValue="List<PicklistSetDto>"
TItem="PicklistSetDto"
@ref="multiObj"
Placeholder="@Label"
@bind-Value="InternalSelectedValues"
AllowFiltering="true"
EnableVirtualization="true"
PopupHeight="300px"
Filtering="OnFilter">
<MultiSelectFieldSettings Text="Text" Value="Value" />
</SfMultiSelect>
⚠ EnableVirtualization="true" improves rendering performance but requires paging logic in OnFilter.
✅ 2. Implement OnFilter with Server-Side Querying
Replace your in-memory filter with actual server-side filtering:
✅ 1. Enable Virtualization
private async Task OnFilter(FilteringEventArgs args)
{
args.PreventDefaultAction = true;
// Server-side call (adjust as needed)
var filtered = await PicklistService.GetFilteredAsync(Name, args.Text);
await multiObj.FilterAsync(filtered, new Query());
}
✅ 3. Modify Your Service to Support Filtering and Paging
public async Task<List<PicklistSetDto>> GetFilteredAsync(Picklist name, string? filter)
{
using var context = _dbContextFactory.CreateDbContext();
var query = context.PicklistSets
.Where(p => p.Name == name);
if (!string.IsNullOrWhiteSpace(filter))
query = query.Where(p => p.Text.Contains(filter));
return await query
.OrderBy(p => p.Text)
.Take(100) // Limit for performance
.Select(p => new PicklistSetDto
{
Value = p.Value,
Text = p.Text,
Name = p.Name
})
.ToListAsync();
}
✅ 4. Optional – Add Debounce to Reduce API Calls
This delays filtering execution until the user stops typing, avoiding too many API hits.
DebounceDelay="300"
Why Use Syncfusion in Blazor?
Syncfusion’s Blazor UI components offer a wide range of benefits for modern web apps. Here’s why it’s a great choice for developers:
✅ 1. Rich Component Library
Syncfusion provides 80+ production-ready components, including:
SfGrid, SfMultiSelect, SfDatePicker, SfDialog, SfChart, and more
Covers everything from data entry to dashboards
⚡ 2. Performance Optimized
Built-in virtualization and lazy loading
Handles large datasets smoothly (e.g., thousands of records in a Grid)
- Consistent UI/UX
Beautiful, modern design out of the box
Theme support: Fluent, Bootstrap5, Material, Tailwind, or your custom styles
- Developer Productivity
Intuitive APIs that follow Blazor standards (@bind-Value, DataSource, events)
Extensive documentation and real-world samples
Native Blazor — not just JS interop wrappers
- Enterprise-Ready Features
Built-in support for localization, accessibility (WCAG 2.0), and RTL
Works seamlessly with validation frameworks like FluentValidation
- Excellent Integration with Modern Blazor Patterns
Compatible with @inject, CascadingParameter, and EventCallback
MVVM-friendly (e.g., CommunityToolkit.MVVM)
Supports reactive forms and dynamic configuration
- Strong Commercial Support
Regular updates and new feature rollouts
Dedicated support via forums and ticket system
Source code access included in paid plans