
Syncfusion Blazor Listview
- 215 installs
- 4 repo stars
- Updated July 28, 2026
- syncfusion/blazor-ui-components-skills
Use syncfusion-blazor-listview for development tasks
About
syncfusion-blazor-listview: A skill for development. This provides functionality for development workflows.
- syncfusion-blazor-listview
Syncfusion Blazor Listview by the numbers
- 215 all-time installs (skills.sh)
- +13 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #1,864 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-listviewAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 215 |
|---|---|
| repo stars | ★ 4 |
| Last updated | July 28, 2026 |
| Repository | syncfusion/blazor-ui-components-skills ↗ |
What it does
Use syncfusion-blazor-listview for development tasks
Files
Implementing Syncfusion Blazor ListView Component
The Syncfusion Blazor ListView component is a feature-rich control for displaying and interacting with lists of data. It supports data binding, custom templates, grouping, filtering, virtualization, and advanced selection modes.
When to Use This Skill
- Setting up ListView - Installation, namespaces, service registration, theme setup
- Binding data - Local data arrays, remote DataManager sources, Entity Framework
- Creating templates - Custom item templates, headers, footers, group headers, device-specific rendering
- Selection & interaction - Checkbox selection, retrieving selected items, click handlers
- Filtering & searching - Real-time search, text filtering, custom filter logic
- Organizing data - Grouping by category, group headers, hierarchical grouping
- Performance - Virtual scrolling for large datasets, container scroll vs window scroll
- Advanced layouts - Grid layouts, dual-list patterns, chat UI, mobile-responsive designs
- Styling & customization - CSS classes, themes, HTML attributes, responsive design
- Event handling - Item selection, navigation, hyperlink integration, list events
Quick Start Example
@using Syncfusion.Blazor.Lists
<SfListView DataSource="@ListData">
<ListViewFieldSettings TValue="DataModel" Id="Id" Text="Text"></ListViewFieldSettings>
</SfListView>
@code {
List<DataModel> ListData = new List<DataModel>();
protected override void OnInitialized()
{
ListData.Add(new DataModel { Text = "Item 1", Id = "1" });
ListData.Add(new DataModel { Text = "Item 2", Id = "2" });
ListData.Add(new DataModel { Text = "Item 3", Id = "3" });
}
public class DataModel
{
public string Id { get; set; }
public string Text { get; set; }
}
}Common Properties & Events
Essential Properties
- DataSource - Array of items or DataManager for binding
- HeaderTitle - Optional header text
- ShowHeader - Display/hide header (boolean)
- EnableCheckbox - Enable checkbox selection (boolean)
- EnableVirtualization - Virtual scrolling for large lists (boolean)
- Height - Container height (required for virtual scrolling)
- ShowCheckBox - Display checkboxes for selection
- SortOrder - Sort items (Ascending/Descending)
Template Properties
- HeaderTemplate - Customize header appearance
- Template - Custom item rendering
- GroupTemplate - Group header customization
- FooterTemplate - Footer customization
Selection & Data
- ListViewFieldSettings - Map data properties:
Id- Item identifierText- Display textGroupBy- Grouping fieldChild- Nested itemsIconCss- Icon classTooltip- Hover tooltip
Documentation and Navigation Guide
Getting Started
📄 Read: references/getting-started.md
- Installation in WebAssembly, Web App, and Server App projects
- Package installation (NuGet)
- Namespace imports and service registration
- Theme stylesheet and script references
- First ListView component setup
- Minimal working example
Data Binding and Sources
📄 Read: references/data-binding-and-source.md
- Local data arrays and JSON binding
- Remote data with DataManager
- OData, OData V4, Web API integration
- Entity Framework binding
- Field mapping with ListViewFieldSettings
- Dynamic data updates and refresh
Templating and Rendering
📄 Read: references/templating-and-rendering.md
- Item template customization
- Header and footer templates
- Group header templates
- Device-specific templates (responsive rendering)
- Template element classes (e-list-template, e-list-wrapper, etc.)
- Avatar and badge templates
- Multi-line items
Item Selection and Actions
📄 Read: references/item-selection-and-actions.md
- GetCheckedItemsAsync method
- Selection with checkboxes
- Single and multiple selection modes
- Retrieving selected item data and indices
- Custom template selection handling
- Click event handlers
Filtering and Searching
📄 Read: references/filtering-and-searching.md
- Real-time search implementation
- Text input filtering
- Filter logic and predicates
- String matching strategies
- Case-insensitive filtering
- Custom filter conditions
Grouping and Organization
📄 Read: references/grouping-and-organization.md
- GroupBy field configuration
- Group header styling
- Collapsible groups
- Category-based organization
- Hierarchical grouping patterns
Virtualization and Performance
📄 Read: references/virtualization-and-performance.md
- EnableVirtualization property
- Window scroll vs container scroll
- Height configuration
- Large dataset handling (1000+ items)
- Performance optimization techniques
- Virtual scrolling limitations and constraints
Advanced Layouts
📄 Read: references/advanced-layouts.md
- Grid layout customization
- Dual-list/multi-select patterns
- Mobile-responsive contact layouts
- Chat window UI implementation
- Layout-specific CSS classes
- Responsive design patterns
Styling and Customization
📄 Read: references/styling-and-customization.md
- CSS class customization (e-listview, e-list-item, e-list-header)
- Theme integration and colors
- Hover state styling
- Selected item styling
- Group header styling
- HTML attribute support
- CSS structure and selectors
Events and Navigation
📄 Read: references/events-and-navigation.md
- ListViewItem event handling
- Click and selection events
- Navigation patterns
- Hyperlink integration and routing
- Event method signatures
- Event context and data
Advanced Patterns
📄 Read: references/advanced-patterns.md
- Nested list implementation
- Add/remove items dynamically
- CRUD operations on ListData
- Complex data scenarios
- Multiple nested levels
- Best practices for hierarchical data
API Reference
📄 Read: references/api-reference.md
- Complete properties documentation with types and defaults
- All component methods with parameters and return types
- Event signatures and event arguments
- Field settings and field mapping configuration
- Template definitions and usage
- Supporting enums (SortOrder, CheckBoxPosition, ListViewEffect)
- Complete working example with all features
Key Props Reference
| Property | Type | Purpose |
|---|---|---|
DataSource | Array/DataManager | Items to display |
HeaderTitle | string | Header text |
ShowHeader | bool | Show/hide header |
ShowCheckBox | bool | Enable checkboxes |
EnableVirtualization | bool | Virtual scrolling |
Height | string | Component height (px) |
SortOrder | SortOrder | Ascending/Descending |
CssClass | string | Custom CSS class |
Template | RenderFragment | Item template |
HeaderTemplate | RenderFragment | Header template |
Common Use Cases
1. Simple list display - Use basic DataSource binding with ListViewFieldSettings 2. Selectable lists - Add ShowCheckBox="true" with GetCheckedItemsAsync() 3. Searchable list - Bind TextBox input to filter DataSource in OnInput events 4. Grouped lists - Map GroupBy field in ListViewFieldSettings 5. Large datasets - Enable virtualization with EnableVirtualization="true" and Height 6. Custom UI - Use Template property with multi-line layouts, avatars, badges 7. Nested lists - Map Child field and use recursive templates 8. Responsive design - Device-specific templates or dynamic templates based on viewport
---
This skill provides architecture and patterns for all ListView scenarios. Reference the specific guide files for detailed implementations and code examples.
Advanced Layouts in Blazor ListView
Table of Contents
Grid Layouts
Transform ListView into a multi-column grid:
@using Syncfusion.Blazor.Lists
<SfListView DataSource="@Products" CssClass="e-list-template">
<ListViewFieldSettings TValue="Product" Id="Id" Text="Name"></ListViewFieldSettings>
<ListViewTemplates TValue="Product">
<Template>
<div class="grid-item">
<img src="@((context as Product).Image)" alt="Product" />
<h4>@((context as Product).Name)</h4>
<p>$@((context as Product).Price)</p>
</div>
</Template>
</ListViewTemplates>
</SfListView>
<style>
.e-listview {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
gap: 16px;
padding: 16px;
}
.grid-item {
border: 1px solid #ddd;
border-radius: 8px;
padding: 12px;
text-align: center;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
cursor: pointer;
transition: transform 0.2s;
}
.grid-item:hover {
transform: translateY(-4px);
box-shadow: 0 4px 8px rgba(0,0,0,0.15);
}
.grid-item img {
width: 100%;
height: 120px;
object-fit: cover;
border-radius: 4px;
}
</style>
@code {
List<Product> Products = new List<Product>
{
new Product { Id = "1", Name = "Product 1", Price = 99.99m, Image = "img1.jpg" },
new Product { Id = "2", Name = "Product 2", Price = 129.99m, Image = "img2.jpg" },
new Product { Id = "3", Name = "Product 3", Price = 79.99m, Image = "img3.jpg" }
};
public class Product
{
public string Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public string Image { get; set; }
}
}Grid Layout with Data Manipulation (CRUD)
Add, remove, sort, and filter items in grid layout:
@using Syncfusion.Blazor.Popups
@using Syncfusion.Blazor.Buttons
@using Syncfusion.Blazor.Lists
@using ListviewSort = Syncfusion.Blazor.Lists.SortOrder
<div id="container">
<div class="sample flex">
<div class="flex">
<!-- Header Controls -->
<div>
<div class="headerContainer">
<div class="e-input-group">
<input id="search" class="e-input" placeholder="Search" @bind-value="@SearchValue" @oninput="@(e => Search(e.Value.ToString()))" />
</div>
<button id="sort" class="e-btn e-small e-round e-primary e-icon-btn" title="Sort" @onclick="@(e => ListSortOrder = (ListSortOrder == ListviewSort.Ascending) ? ListviewSort.Descending : ListviewSort.Ascending)">
<span class="e-btn-icon e-icons @(ListSortOrder == ListviewSort.Ascending ? "e-sort-icon-ascending" : "e-sort-icon-descending")\"></span>
</button>
<button id="add" class="e-btn e-small e-round e-primary e-icon-btn" title="Add" @onclick="@(e => DialogObj.ShowAsync())">
<span class="e-btn-icon e-icons e-add-icon\"></span>
</button>
</div>
</div>
<!-- Add Item Dialog -->
<SfDialog @ref="DialogObj" Target="#container" ShowCloseIcon="true" Header="Add item" @bind-Visible="@Visible" Width="300px" Height="230px">
<DialogTemplates>
<Content>
<div id="listDialog">
<div class="input_name">
<label for="name">Item text: </label>
<input id="name" class="e-input" type="text" placeholder="Enter text" @bind-value="@Value" />
</div>
</div>
</Content>
</DialogTemplates>
<DialogButtons>
<DialogButton OnClick="@(e => Add())" Content="Add" IsPrimary="true" CssClass="e-flat\"></DialogButton>
</DialogButtons>
</SfDialog>
<!-- Grid ListView -->
<div class="listview-container">
<SfListView ID="element" DataSource="@DataSource" SortOrder="@ListSortOrder" CssClass="e-list-template grid-view">
<ListViewFieldSettings TValue="ListDataModel" Id="Id" Text="Text\"></ListViewFieldSettings>
<ListViewTemplates TValue="ListDataModel">
<Template>
@{
ListDataModel currentData = (ListDataModel)context;
<div class="grid-item-box">
<div>@currentData.Text</div>
<button class="delete e-control e-btn e-small e-round e-delete-btn e-primary e-icon-btn" @onclick="@(e => Remove(currentData))">
<span class="e-btn-icon e-icons delete-icon">✕</span>
</button>
</div>
}
</Template>
</ListViewTemplates>
</SfListView>
</div>
</div>
</div>
</div>
@code {
SfDialog DialogObj;
bool Visible;
string Value = "";
string SearchValue = "";
ListviewSort ListSortOrder = ListviewSort.Ascending;
List<ListDataModel> DataSource;
List<ListDataModel> DataSourceOG = new List<ListDataModel>()
{
new ListDataModel { Id = "1", Text = "Item 1" },
new ListDataModel { Id = "2", Text = "Item 2" },
new ListDataModel { Id = "3", Text = "Item 3" },
new ListDataModel { Id = "4", Text = "Item 4" },
new ListDataModel { Id = "5", Text = "Item 5" }
};
protected override void OnInitialized()
{
DataSource = new List<ListDataModel>(DataSourceOG);
}
async void Add()
{
await DialogObj.HideAsync();
DataSourceOG.Add(new ListDataModel { Id = Guid.NewGuid().ToString(), Text = Value });
DataSource = new List<ListDataModel>(DataSourceOG);
Value = "";
}
void Remove(ListDataModel data)
{
var index = DataSourceOG.FindIndex(e => e.Id == data.Id);
if (index >= 0)
{
DataSourceOG.RemoveAt(index);
DataSource = new List<ListDataModel>(DataSourceOG);
}
}
void Search(string value)
{
SearchValue = value;
if (string.IsNullOrEmpty(value))
{
DataSource = new List<ListDataModel>(DataSourceOG);
}
else
{
DataSource = DataSourceOG.Where(x => x.Text.ToLower().Contains(value.ToLower())).ToList();
}
}
public class ListDataModel
{
public string Id { get; set; }
public string Text { get; set; }
}
}
<style>
#container .e-listview.grid-view {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
background: none;
border: none;
padding: 10px;
}
#container .e-listview.grid-view .e-list-item {
height: auto;
border: 1px solid #ddd;
padding: 10px;
text-align: center;
border-radius: 4px;
}
.grid-item-box {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 8px;
}
.delete-icon {
cursor: pointer;
color: red;
}
</style>Dual-List Patterns
Dual List with Data Manipulation
Create two ListViews with buttons to move items between them, with filtering and sorting support:
@using Syncfusion.Blazor.Inputs
@using Syncfusion.Blazor.Lists
<div id="container">
<div class="sample flex">
<div class="flex">
<!-- First List -->
<div class="padding">
<SfTextBox Placeholder="Filter" Input="@(e => OnInput(e, 1))"></SfTextBox>
<SfListView DataSource="@FirstData" SortOrder="SortOrder.Ascending">
<ListViewFieldSettings TValue="ListDataModel" Id="Id" Text="Text"></ListViewFieldSettings>
<ListViewEvents TValue="ListDataModel" Clicked="@(e => OnSelected(e, 1))"></ListViewEvents>
</SfListView>
</div>
<!-- Transfer Buttons -->
<div class="flex vertical vertical__center flex__center padding">
<div class="padding">
<button disabled="@(!FirstListData.Any())" class="e-btn" @onclick="@(e => OnButtonClick(1))">≫</button>
</div>
<div class="padding">
<button disabled="@(FirstSelected == null)" class="e-btn" @onclick="@(e => OnButtonClick(2))">></button>
</div>
<div class="padding">
<button disabled="@(SecondSelected == null)" class="e-btn" @onclick="@(e => OnButtonClick(3))"><</button>
</div>
<div class="padding">
<button disabled="@(!SecondListData.Any())" class="e-btn" @onclick="@(e => OnButtonClick(4))">«</button>
</div>
</div>
<!-- Second List -->
<div class="padding">
<SfTextBox Placeholder="Filter" Input="@(e => OnInput(e, 2))"></SfTextBox>
<SfListView DataSource="@SecondData" SortOrder="SortOrder.Ascending">
<ListViewFieldSettings Id="Id" Text="Text" TValue="ListDataModel"></ListViewFieldSettings>
<ListViewEvents TValue="ListDataModel" Clicked="@(e => OnSelected(e, 2))"></ListViewEvents>
</SfListView>
</div>
</div>
</div>
</div>
@code {
List<ListDataModel> FirstData;
List<ListDataModel> SecondData;
ListDataModel FirstSelected;
ListDataModel SecondSelected;
List<ListDataModel> FirstListData = new List<ListDataModel>()
{
new ListDataModel { Text = "Hennessey Venom", Id = "01" },
new ListDataModel { Text = "Bugatti Chiron", Id = "02" },
new ListDataModel { Text = "Bugatti Veyron Super Sport", Id = "03" },
new ListDataModel { Text = "SSC Ultimate Aero", Id = "04" },
new ListDataModel { Text = "Koenigsegg CCR", Id = "05" }
};
List<ListDataModel> SecondListData = new List<ListDataModel>()
{
new ListDataModel { Text = "McLaren P1", Id = "09" },
new ListDataModel { Text = "Ferrari LaFerrari", Id = "10" }
};
protected override void OnInitialized()
{
FirstData = new List<ListDataModel>(FirstListData);
SecondData = new List<ListDataModel>(SecondListData);
}
void OnButtonClick(int buttonIndex)
{
switch (buttonIndex)
{
case 1: // Move All
FirstListData.ForEach(e => SecondListData.Add(e));
FirstListData.Clear();
FirstData = new List<ListDataModel>(FirstListData);
SecondData = new List<ListDataModel>(SecondListData);
break;
case 2: // Move Selected Right
if (FirstSelected != null)
{
SecondListData.Add(FirstSelected);
FirstListData.RemoveAt(FirstListData.FindIndex(e => e.Id == FirstSelected.Id));
FirstData = new List<ListDataModel>(FirstListData);
SecondData = new List<ListDataModel>(SecondListData);
FirstSelected = null;
}
break;
case 3: // Move Selected Left
if (SecondSelected != null)
{
FirstListData.Add(SecondSelected);
SecondListData.RemoveAt(SecondListData.FindIndex(e => e.Id == SecondSelected.Id));
FirstData = new List<ListDataModel>(FirstListData);
SecondData = new List<ListDataModel>(SecondListData);
SecondSelected = null;
}
break;
case 4: // Move All Left
SecondListData.ForEach(e => FirstListData.Add(e));
SecondListData.Clear();
FirstData = new List<ListDataModel>(FirstListData);
SecondData = new List<ListDataModel>(SecondListData);
break;
}
}
void OnSelected(ClickEventArgs<ListDataModel> eventArgs, int listviewIndex)
{
if (listviewIndex == 1)
{
FirstSelected = eventArgs.ItemData;
}
else
{
SecondSelected = eventArgs.ItemData;
}
}
void OnInput(InputEventArgs eventArgs, int listviewIndex)
{
if (listviewIndex == 1)
{
FirstData = FirstListData.FindAll(e => e.Text.ToLower().Contains(eventArgs.Value.ToLower()));
}
else
{
SecondData = SecondListData.FindAll(e => e.Text.ToLower().Contains(eventArgs.Value.ToLower()));
}
}
public class ListDataModel
{
public string Id { get; set; }
public string Text { get; set; }
}
}
<style>
.flex {
display: flex;
}
.vertical {
flex-direction: column;
}
.vertical__center {
justify-content: center;
}
.flex__center {
justify-content: center;
}
.padding {
padding: 4px;
}
#container .e-listview {
width: 300px;
height: 300px;
}
</style>Mobile-Responsive Layouts
Mobile Contact Layout with Avatar
Create a professional contact list with avatar support (both text initials and images):
@using Syncfusion.Blazor.Lists
<div class="flex flex__center">
<div class="margin">
<SfListView DataSource="@DataSource"
ShowHeader="true"
HeaderTitle="Contacts"
CssClass="e-list-template"
SortOrder="SortOrder.Ascending">
<ListViewFieldSettings TValue="ListDataModel" Id="Id" Text="Text"></ListViewFieldSettings>
<ListViewTemplates TValue="ListDataModel">
<Template>
@{
ListDataModel item = context as ListDataModel;
<div class="e-list-wrapper e-list-multi-line e-list-avatar">
@if (!string.IsNullOrEmpty(item.Avatar))
{
<span class="e-avatar e-avatar-circle">@item.Avatar</span>
}
else
{
<span class="@item.Pic e-avatar e-avatar-circle"></span>
}
<span class="e-list-item-header">@item.Text</span>
<span class="e-list-content">@item.Contact</span>
</div>
}
</Template>
</ListViewTemplates>
</SfListView>
</div>
</div>
@code {
List<ListDataModel> DataSource = new List<ListDataModel>()
{
new ListDataModel { Text = "Jennifer", Contact = "(206) 555-985774", Id = "1", Avatar = "JE" },
new ListDataModel { Text = "Amenda", Contact = "(206) 555-3412", Id = "2", Avatar = "AM" },
new ListDataModel { Text = "Isabella", Contact = "(206) 555-8122", Id = "4", Avatar = "IS" },
new ListDataModel { Text = "William", Contact = "(206) 555-9482", Id = "5", Avatar = "WI" },
new ListDataModel { Text = "Jacob", Contact = "(71) 555-4848", Id = "6", Avatar = "JA" },
new ListDataModel { Text = "Charlotte", Contact = "(206) 555-1189", Id = "9", Avatar = "CH" }
};
public class ListDataModel
{
public string Id { get; set; }
public string Text { get; set; }
public string Avatar { get; set; }
public string Pic { get; set; }
public string Contact { get; set; }
}
}
<style>
.flex {
display: flex;
}
.flex__center {
justify-content: center;
}
.margin {
margin: 10px;
width: 350px;
}
</style>Responsive Contact Layout
@using Syncfusion.Blazor.Lists
<SfListView DataSource="@Contacts"
CssClass="e-list-template contact-list"
ShowHeader="true"
HeaderTitle="Contacts">
<ListViewFieldSettings TValue="Contact" Id="Id" Text="Name"></ListViewFieldSettings>
<ListViewTemplates TValue="Contact">
<Template>
<div class="e-list-wrapper e-list-multi-line contact-item">
<img class="contact-avatar" src="@((context as Contact).Avatar)" />
<div class="contact-info">
<span class="e-list-item-header">@((context as Contact).Name)</span>
<span class="e-list-content phone">@((context as Contact).Phone)</span>
<span class="e-list-content email">@((context as Contact).Email)</span>
</div>
</div>
</Template>
</ListViewTemplates>
</SfListView>
<style>
.contact-list {
margin: 0;
padding: 0;
}
.contact-item {
padding: 12px 16px;
border-bottom: 1px solid #f0f0f0;
}
.contact-avatar {
width: 48px;
height: 48px;
border-radius: 50%;
object-fit: cover;
margin-right: 12px;
}
.contact-info {
display: flex;
flex-direction: column;
flex: 1;
}
.contact-info .phone {
font-size: 12px;
color: #666;
}
.contact-info .email {
font-size: 12px;
color: #999;
display: none;
}
/* Mobile: Show phone, hide email */
@media (max-width: 600px) {
.contact-avatar {
width: 40px;
height: 40px;
}
.contact-info .phone {
display: block;
}
.contact-info .email {
display: none;
}
}
/* Desktop: Show both phone and email */
@media (min-width: 601px) {
.contact-avatar {
width: 56px;
height: 56px;
}
.contact-info .email {
display: block;
}
}
</style>
@code {
List<Contact> Contacts = new List<Contact>
{
new Contact { Id = "1", Name = "John Doe", Phone = "(555) 123-4567", Email = "john@example.com", Avatar = "avatar1.jpg" },
new Contact { Id = "2", Name = "Jane Smith", Phone = "(555) 234-5678", Email = "jane@example.com", Avatar = "avatar2.jpg" }
};
public class Contact
{
public string Id { get; set; }
public string Name { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
public string Avatar { get; set; }
}
}Chat Window UI
Message Bubble Layout
@using Syncfusion.Blazor.Lists
<div style="display: flex; flex-direction: column; height: 100vh;">
<!-- Chat view -->
<SfListView DataSource="@Messages"
CssClass="chat-list"
EnableVirtualization="true"
Height="400px">
<ListViewFieldSettings TValue="Message" Id="Id" Text="Text"></ListViewFieldSettings>
<ListViewTemplates TValue="Message">
<Template>
@{
var msg = context as Message;
<div class="message-container" style="text-align: @(msg.IsOwn ? "right" : "left"); margin: 8px 0;">
<div class="message-bubble" style="
background-color: @(msg.IsOwn ? "#0084ff" : "#e5e5ea");
color: @(msg.IsOwn ? "white" : "black");
padding: 8px 12px;
border-radius: 16px;
display: inline-block;
max-width: 70%;
word-wrap: break-word;
">
@msg.Text
</div>
<div style="font-size: 12px; color: #999; margin-top: 4px;">
@msg.Time
</div>
</div>
}
</Template>
</ListViewTemplates>
</SfListView>
<!-- Input -->
<div style="padding: 12px; border-top: 1px solid #ddd;">
<div style="display: flex; gap: 8px;">
<input type="text" placeholder="Type a message..." style="flex: 1; padding: 8px;" @bind="newMessage" />
<button class="e-btn" @onclick="SendMessage">Send</button>
</div>
</div>
</div>
@code {
List<Message> Messages = new List<Message>();
string newMessage = "";
protected override void OnInitialized()
{
Messages.Add(new Message { Id = "1", Text = "Hello!", IsOwn = true, Time = "10:30 AM" });
Messages.Add(new Message { Id = "2", Text = "Hi there!", IsOwn = false, Time = "10:31 AM" });
}
void SendMessage()
{
if (!string.IsNullOrEmpty(newMessage))
{
Messages.Add(new Message
{
Id = (Messages.Count + 1).ToString(),
Text = newMessage,
IsOwn = true,
Time = DateTime.Now.ToString("h:mm tt")
});
newMessage = "";
}
}
public class Message
{
public string Id { get; set; }
public string Text { get; set; }
public bool IsOwn { get; set; }
public string Time { get; set; }
}
}Layout-Specific CSS
Common Layout Classes
/* Flex layout for horizontal arrangement */
.layout-flex {
display: flex;
gap: 16px;
}
/* Grid layout for multiple items per row */
.layout-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 16px;
}
/* Two-column layout */
.layout-two-column {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
}
/* Sidebar layout */
.layout-sidebar {
display: flex;
}
.layout-sidebar-nav {
width: 250px;
border-right: 1px solid #ddd;
overflow-y: auto;
}
.layout-sidebar-content {
flex: 1;
overflow-y: auto;
}
/* Responsive adjustments */
@media (max-width: 768px) {
.layout-grid {
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}
.layout-two-column {
grid-template-columns: 1fr;
}
.layout-sidebar {
flex-direction: column;
}
.layout-sidebar-nav {
width: 100%;
border-right: none;
border-bottom: 1px solid #ddd;
}
}---
Related Topics:
- Templating and Rendering - Create layout templates
- Item Selection and Actions - Interaction in layouts
- Virtualization and Performance - Performance for large layouts
Advanced Patterns in Blazor ListView
Table of Contents
Nested Lists
Three-Level Hierarchy
@using Syncfusion.Blazor.Lists
<SfListView DataSource="@ListData" ShowHeader="true" HeaderTitle="Continent">
<ListViewFieldSettings TValue="DataModel"
Id="Id"
Text="Text"
Child="Child">
</ListViewFieldSettings>
</SfListView>
@code {
List<DataModel> ListData = new List<DataModel>();
protected override void OnInitialized()
{
base.OnInitialized();
// Level 1: Continents
ListData.Add(new DataModel
{
Text = "Asia",
Id = "01",
Child = new List<DataModel>()
{
// Level 2: Countries
new DataModel
{
Text = "India",
Id = "1",
Child = new List<DataModel>()
{
// Level 3: Cities
new DataModel { Text = "Delhi", Id = "1001" },
new DataModel { Text = "Mumbai", Id = "1002" },
new DataModel { Text = "Bangalore", Id = "1003" }
}
},
new DataModel
{
Text = "China",
Id = "2",
Child = new List<DataModel>()
{
new DataModel { Text = "Beijing", Id = "2001" },
new DataModel { Text = "Shanghai", Id = "2002" },
new DataModel { Text = "Shenzhen", Id = "2003" }
}
}
}
});
ListData.Add(new DataModel
{
Text = "Europe",
Id = "02",
Child = new List<DataModel>()
{
new DataModel
{
Text = "Germany",
Id = "3",
Child = new List<DataModel>()
{
new DataModel { Text = "Berlin", Id = "3001" },
new DataModel { Text = "Munich", Id = "3002" }
}
}
}
});
}
public class DataModel
{
public string Id { get; set; }
public string Text { get; set; }
public List<DataModel> Child { get; set; }
}
}Custom Nested Templates
<SfListView DataSource="@OrganizationData" CssClass="e-list-template">
<ListViewFieldSettings TValue="OrganizationUnit"
Id="Id"
Text="Name"
Child="Departments">
</ListViewFieldSettings>
<ListViewTemplates TValue="OrganizationUnit">
<Template>
<div class="e-list-wrapper e-list-multi-line">
<span class="e-list-item-header">@((context as OrganizationUnit).Name)</span>
@if ((context as OrganizationUnit).Departments?.Count > 0)
{
<span class="e-list-content">
@((context as OrganizationUnit).Departments.Count) departments
</span>
}
</div>
</Template>
</ListViewTemplates>
</SfListView>
@code {
List<OrganizationUnit> OrganizationData = new List<OrganizationUnit>
{
new OrganizationUnit
{
Id = "1",
Name = "Engineering",
Departments = new List<OrganizationUnit>
{
new OrganizationUnit { Id = "1-1", Name = "Backend" },
new OrganizationUnit { Id = "1-2", Name = "Frontend" }
}
},
new OrganizationUnit
{
Id = "2",
Name = "Sales",
Departments = new List<OrganizationUnit>
{
new OrganizationUnit { Id = "2-1", Name = "Enterprise" },
new OrganizationUnit { Id = "2-2", Name = "SMB" }
}
}
};
public class OrganizationUnit
{
public string Id { get; set; }
public string Name { get; set; }
public List<OrganizationUnit> Departments { get; set; }
}
}Add and Remove Items Dynamically
Using ObservableCollection
@using Syncfusion.Blazor.Lists
@using System.Collections.ObjectModel
<div class="flex">
<div class="margin">
<SfListView ID="sample-list" DataSource="@DataSource">
<ListViewFieldSettings TValue="ListDataModel" Id="Id" Text="Text"></ListViewFieldSettings>
<ListViewTemplates TValue="ListDataModel">
<Template>
@{
ListDataModel item = context as ListDataModel;
<div class="text-content">
@item.Text
<span class="delete-icon" @onclick="@(() => { OnDelete(item); })"></span>
</div>
}
</Template>
</ListViewTemplates>
</SfListView>
</div>
</div>
<div class="flex">
<button class="e-btn" @onclick="@AddItem">Add Item</button>
</div>
@code {
ObservableCollection<ListDataModel> DataSource = new ObservableCollection<ListDataModel>()
{
new ListDataModel{ Id = "1", Text = "Artwork"},
new ListDataModel{ Id = "2", Text = "Abstract"},
new ListDataModel{ Id = "3", Text = "Modern Painting"},
new ListDataModel{ Id = "4", Text = "Ceramics"},
new ListDataModel{ Id = "5", Text = "Animation Art"},
new ListDataModel{ Id = "6", Text = "Oil Painting"},
};
void OnDelete(ListDataModel listDataModel)
{
var index = DataSource.ToList().FindIndex(e => e.Id == listDataModel.Id);
if (index >= 0)
{
DataSource.RemoveAt(index);
}
}
void AddItem()
{
var random = new Random();
DataSource.Add(new ListDataModel
{
Id = random.Next(100, 300).ToString(),
Text = "Item " + random.Next(100, 300).ToString(),
});
}
public class ListDataModel
{
public string Id { get; set; }
public string Text { get; set; }
}
}
<style>
.flex {
display: flex;
justify-content: center;
}
.margin {
margin: 10px;
width: 300px;
}
#sample-list .delete-icon::after {
content: "\e878";
float: right;
cursor: pointer;
color: red;
}
.text-content {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>CRUD Operations
Insert Operation
void InsertItem(ListDataModel newItem)
{
DataSource.Add(newItem);
// ObservableCollection automatically triggers UI update
}
void InsertAtIndex(ListDataModel newItem, int index)
{
DataSource.Insert(index, newItem);
}Update Operation
void UpdateItem(string id, ListDataModel updatedItem)
{
var existingItem = DataSource.FirstOrDefault(x => x.Id == id);
if (existingItem != null)
{
var index = DataSource.IndexOf(existingItem);
DataSource[index] = updatedItem;
}
}
void UpdateItemProperty(string id, string newText)
{
var item = DataSource.FirstOrDefault(x => x.Id == id);
if (item != null)
{
item.Text = newText;
// Update view
StateHasChanged();
}
}Delete Operation
void DeleteItem(string id)
{
var item = DataSource.FirstOrDefault(x => x.Id == id);
if (item != null)
{
DataSource.Remove(item);
}
}
void DeleteAtIndex(int index)
{
if (index >= 0 && index < DataSource.Count)
{
DataSource.RemoveAt(index);
}
}
void DeleteAll()
{
DataSource.Clear();
}Read/Retrieve Operations
ListDataModel GetItemById(string id)
{
return DataSource.FirstOrDefault(x => x.Id == id);
}
List<ListDataModel> GetItemsByCategory(string category)
{
return DataSource.Where(x => x.Category == category).ToList();
}
int GetItemCount()
{
return DataSource.Count;
}Complex Data Scenarios
Hierarchical Data with Mixed Types
public class TreeNode
{
public string Id { get; set; }
public string Name { get; set; }
public NodeType Type { get; set; }
public List<TreeNode> Children { get; set; }
public Dictionary<string, object> Metadata { get; set; }
}
public enum NodeType
{
Folder,
File,
Item
}
// Create complex nested structure
var fileSystem = new TreeNode
{
Id = "root",
Name = "Documents",
Type = NodeType.Folder,
Children = new List<TreeNode>
{
new TreeNode
{
Id = "folder1",
Name = "Projects",
Type = NodeType.Folder,
Children = new List<TreeNode>
{
new TreeNode { Id = "file1", Name = "project.md", Type = NodeType.File },
new TreeNode { Id = "file2", Name = "notes.txt", Type = NodeType.File }
}
},
new TreeNode { Id = "file3", Name = "resume.pdf", Type = NodeType.File }
}
};Filtered and Grouped Data
// Get filtered and grouped data
var groupedItems = AllItems
.Where(x => x.Active == true)
.GroupBy(x => x.Category)
.Select(g => new GroupedData
{
Category = g.Key,
Items = g.ToList(),
ItemCount = g.Count()
})
.ToList();Asynchronous Data Loading
@using System.Net.Http.Json
<SfListView DataSource="@LoadedItems">
<ListViewFieldSettings TValue="Item" Id="Id" Text="Name"></ListViewFieldSettings>
</SfListView>
<button @onclick="LoadMoreItems">Load More</button>
@code {
List<Item> LoadedItems = new List<Item>();
private int pageNumber = 1;
async Task LoadMoreItems()
{
try
{
var newItems = await Http.GetFromJsonAsync<List<Item>>(
$"/api/items?page={pageNumber}&pageSize=10"
);
if (newItems != null)
{
LoadedItems.AddRange(newItems);
pageNumber++;
}
}
catch (Exception ex)
{
Console.WriteLine($"Error loading items: {ex.Message}");
}
}
public class Item
{
public string Id { get; set; }
public string Name { get; set; }
}
}Best Practices
1. Use ObservableCollection for Dynamic Lists
// ✅ GOOD: Changes automatically update UI
ObservableCollection<Item> Items = new ObservableCollection<Item>();
Items.Add(new Item());
// ❌ AVOID: Manual StateHasChanged required
List<Item> Items = new List<Item>();
Items.Add(new Item());
StateHasChanged();2. Key by Unique Identifier
// Ensure each item has unique Id
Items.Add(new Item
{
Id = Guid.NewGuid().ToString(), // Unique
Name = "New Item"
});3. Handle Null References
void RemoveItem(Item item)
{
if (item != null && !string.IsNullOrEmpty(item.Id))
{
Items.Remove(item);
}
}4. Optimize Performance with Large Lists
// Use virtualization for 500+ items
// Implement pagination
// Lazy-load children
<SfListView DataSource="@Items"
EnableVirtualization="true"
Height="500px">
</SfListView>5. Proper State Management
// Track changes
private List<Item> deletedItems = new List<Item>();
private List<Item> addedItems = new List<Item>();
private List<Item> modifiedItems = new List<Item>();
// Provide undo/redo capability
void Undo()
{
// Restore to previous state
}6. Error Handling in CRUD
async Task SafeAddItem(Item newItem)
{
try
{
ValidateItem(newItem);
Items.Add(newItem);
await SaveToServer(newItem);
}
catch (ValidationException ex)
{
// Handle validation errors
ShowError(ex.Message);
}
catch (Exception ex)
{
// Handle unexpected errors
showError("Failed to add item");
}
}
void ValidateItem(Item item)
{
if (string.IsNullOrEmpty(item.Name))
throw new ValidationException("Name is required");
}---
Related Topics:
- Data Binding and Sources - Complex data sources
- Item Selection and Actions - CRUD event handling
- Virtualization and Performance - Performance optimization
Syncfusion Blazor ListView API Reference
Overview
The SfListView<TValue> component displays data in an interactive hierarchical structure with features like data-binding, templates, grouping, virtualization, and selection capabilities. This API reference covers all properties, methods, and events.
Table of Contents
- Properties
- Methods
- Events
- Event Arguments Reference
- ClickEventArgs
- ActionEventsArgs
- ActionFailureEventsArgs
- BackEventArgs
- Field Settings
- Templates
- Supporting Enums and Classes
- AnimationSettings
- SortOrder Enum
- CheckBoxPosition Enum
- SelectedItems
- Complete Usage Example
- Additional Property Examples
- Property: Enabled
- Property: EnablePersistence
- Property: EnableRtl
- Property: HtmlAttributes
- Property: ID
- Property: ShowIcon
- Property: Width
- Navigation Guide
---
Properties
| Property | Type | Default | Accepted Values | Description | Reference |
|---|---|---|---|---|---|
Animation | AnimationSettings | SlideLeft (400ms) | Effect, Duration, Easing | Animation settings for nested navigation | view |
CheckBoxPosition | CheckBoxPosition | Left | Left, Right | Position of checkbox in list items | view |
CssClass | string | String.Empty | Any CSS class(es) | Custom CSS class(es) for styling | view |
DataSource | IEnumerable<TValue> | null | Any collection | Data to be rendered in the ListView | view |
Enabled | bool | true | true, false | Enable/disable component interaction | example |
EnablePersistence | bool | false | true, false | Persist checked items between page reloads | example |
EnableRtl | bool | false | true, false | Enable right-to-left text direction | example |
EnableVirtualization | bool | false | true, false | Enable virtualization for large datasets | view |
GroupTemplate | RenderFragment<ComposedItemModel<TValue>> | null | Custom HTML/Components | Custom template for group headers | view |
HeaderTemplate | RenderFragment | null | Custom HTML/Components | Custom template for header title | view |
HeaderTitle | string | String.Empty | Any text | Header title text | view |
Height | string | - | CSS height value | Component height (px, %, em, etc) | view |
HtmlAttributes | Dictionary<string, object> | null | Key-value pairs | Additional HTML attributes for root element | example |
ID | string | - | Any ID value | Component element ID | example |
Query | Query | null | Query with where/select | DataManager query for filtering/selection | view |
ShowCheckBox | bool | false | true, false | Display/hide checkboxes in list items | view |
ShowHeader | bool | false | true, false | Display/hide header section | view |
ShowIcon | bool | false | true, false | Display/hide list item icons | example |
SortOrder | SortOrder | None | None, Ascending, Descending | Sort order for list items | view |
Template | RenderFragment<TValue> | null | Custom HTML/Components | Custom template for list items | view |
Width | string | - | CSS width value | Component width (px, %, em, etc) | example |
---
Methods
| Method | Parameters | Return Type | Description | Reference |
|---|---|---|---|---|
GetCheckedItemsAsync() | None | Task<SelectedItems<TValue>> | Get all currently checked items | view |
CheckItemsAsync(listItems) | IEnumerable<TValue> items (optional) | Task | Check specific items or all items | example |
UncheckItemsAsync(listItems) | IEnumerable<TValue> items (optional) | Task | Uncheck specific items or all items | example |
EnableItemAsync(listItem) | TValue item | Task | Enable a previously disabled item | example |
DisableItemAsync(listItem) | TValue item | Task | Disable a specific item | example |
RemoveItems(listItems) | IEnumerable<TValue> items | void | Remove items from the ListView | example |
UpdateListViewDataSource(updateSortedData, dataSource) | bool updateSortedData (optional), IEnumerable<TValue> dataSource (optional) | void | Update ListView datasource with optional sorting | example |
Code Example for CheckItemsAsync:
```csharp
// Check specific items
var itemsToCheck = new List<DataModel>
{
new DataModel { Id = "1", Text = "Item 1" },
new DataModel { Id = "2", Text = "Item 2" }
};
await ListViewRef.CheckItemsAsync(itemsToCheck);
>
// Check all items
await ListViewRef.CheckItemsAsync();
```
Method: UncheckItemsAsync
// Uncheck specific items
var itemsToUncheck = new List<DataModel>
{
new DataModel { Id = "1", Text = "Item 1" }
};
await ListViewRef.UncheckItemsAsync(itemsToUncheck);
// Uncheck all items
await ListViewRef.UncheckItemsAsync();Method: EnableItemAsync
// Enable item that was previously disabled
var itemToEnable = new DataModel { Id = "1", Text = "Item 1" };
await ListViewRef.EnableItemAsync(itemToEnable);Method: DisableItemAsync
// Disable a specific item
var itemToDisable = new DataModel { Id = "2", Text = "Item 2" };
await ListViewRef.DisableItemAsync(itemToDisable);Method: RemoveItems
// Remove specific items from ListView
var itemsToRemove = new List<DataModel>
{
new DataModel { Id = "1", Text = "Item 1" },
new DataModel { Id = "3", Text = "Item 3" }
};
ListViewRef.RemoveItems(itemsToRemove);Method: UpdateListViewDataSource
// Update datasource with new data
var newData = new List<DataModel>
{
new DataModel { Id = "1", Text = "Updated Item 1" },
new DataModel { Id = "2", Text = "Updated Item 2" },
new DataModel { Id = "3", Text = "New Item 3" }
};
// Update datasource only
ListViewRef.UpdateListViewDataSource(false, newData);
// Update datasource and refresh sorted data
ListViewRef.UpdateListViewDataSource(true, newData);
// Update only sorting (keep current datasource)
ListViewRef.UpdateListViewDataSource(true);
// Refresh current datasource with sorting
ListViewRef.UpdateListViewDataSource(true, ListViewRef.DataSource);---
Events
| Event | Arguments | Description | Reference |
|---|---|---|---|
Clicked | ClickEventArgs<TValue> | Fires when a list item is clicked | view |
Created | object | Fires when the component is created | example |
Destroyed | object | Fires when the component is destroyed | example |
OnActionBegin | ActionEventsArgs | Fires at the beginning of each ListView action | view |
OnActionComplete | ActionEventsArgs | Fires when a ListView action completes | view |
OnActionFailure | ActionFailureEventsArgs | Fires when remote data fetch fails | example |
OnBack | BackEventArgs<TValue> | Fires when back icon is clicked in nested list | example |
Event: Created
void OnCreated()
{
Console.WriteLine("ListView component created and rendered");
// Initialize any dependent logic
}Event: Destroyed
void OnDestroyed()
{
Console.WriteLine("ListView component destroyed");
// Cleanup resources if needed
}Event: OnActionFailure
void OnActionFailure(ActionFailureEventsArgs args)
{
// Triggered when remote datasource fails to fetch data
Console.WriteLine($"Error fetching data: {args.Error}");
// Handle error appropriately - show user message, retry logic, etc.
}Event: OnBack
void OnBack(BackEventArgs<TValue> args)
{
// Triggered when back button is clicked in nested list navigation
Console.WriteLine($"Going back from list. Current item: {args.Text}");
}---
Field Settings
Configure field mappings for your data model using ListViewFieldSettings<TValue>:
| Property | Type | Default | Description | Reference |
|---|---|---|---|---|
Id | string | String.Empty | Unique identifier field | view |
Text | string | String.Empty | Display text field | view |
Tooltip | string | String.Empty | Tooltip text field | example |
IconCss | string | String.Empty | Icon CSS class field | example |
Child | string | String.Empty | Nested items field (for hierarchical data) | view |
GroupBy | string | String.Empty | Field to group items by | view |
IsChecked | string | String.Empty | Checkbox state field | view |
Enabled | string | String.Empty | Item enabled/disabled state field | example |
HtmlAttributes | string | String.Empty | HTML attributes field | example |
Field: Tooltip
<ListViewFieldSettings TValue="Product"
Id="Id"
Text="Name"
Tooltip="Description">
</ListViewFieldSettings>
// Data model
public class Product
{
public string Id { get; set; }
public string Name { get; set; }
public string Description { get; set; } // Maps to Tooltip
}Field: IconCss
<ListViewFieldSettings TValue="MenuItem"
Id="Id"
Text="Label"
IconCss="Icon">
</ListViewFieldSettings>
// Data model with FontAwesome icons
public class MenuItem
{
public string Id { get; set; }
public string Label { get; set; }
public string Icon { get; set; } = "fa-home"; // FontAwesome class
}Field: Enabled
<ListViewFieldSettings TValue="MenuItem"
Id="Id"
Text="Label"
Enabled="IsActive">
</ListViewFieldSettings>
// When IsActive is false, the item appears disabled
public class MenuItem
{
public string Id { get; set; }
public string Label { get; set; }
public bool IsActive { get; set; } = true;
}Field: HtmlAttributes
<ListViewFieldSettings TValue="Product"
Id="Id"
Text="Name"
HtmlAttributes="CssClasses">
</ListViewFieldSettings>
// Apply custom CSS classes to items
public class Product
{
public string Id { get; set; }
public string Name { get; set; }
public string CssClasses { get; set; } = "custom-item highlight";
}---
Templates
Configure custom rendering using ListViewTemplates<TValue>:
| Template | Type | Description | Reference |
|---|---|---|---|
Template | RenderFragment<TValue> | Custom template for individual list items | view |
HeaderTemplate | RenderFragment | Custom template for the component header | view |
GroupTemplate | RenderFragment<ComposedItemModel<TValue>> | Custom template for group headers | view |
---
Supporting Enums and Classes
AnimationSettings
Configuration for animation effects:
| Property | Type | Default | Description |
|---|---|---|---|
Effect | ListViewEffect | SlideLeft | Animation effect type |
Duration | int | 400 | Animation duration in milliseconds |
Easing | string | "ease" | CSS easing function |
ListViewEffect Values:
None- No animationSlideLeft- Slide left animationSlideDown- Slide down animationZoom- Zoom animationFade- Fade animation
Code Example:
```csharp
public AnimationSettings ListAnimation { get; set; } = new AnimationSettings()
{
Effect = ListViewEffect.Zoom,
Duration = 500,
Easing = "ease-in-out"
};
```
SortOrder Enum
| Value | Description |
|---|---|
None | No sorting |
Ascending | Sort in ascending order (A→Z, 0→9) |
Descending | Sort in descending order (Z→A, 9→0) |
CheckBoxPosition Enum
| Value | Description |
|---|---|
Left | Checkbox appears before item text (default) |
Right | Checkbox appears after item text |
SelectedItems<TValue> Class
Return type for GetCheckedItemsAsync():
| Property | Type | Description |
|---|---|---|
Data | List<TValue> | Array of selected item objects |
Text | List<string> | Array of selected item text values |
Index | List<int> | Array of selected item indices (virtualization only) |
ParentId | List<string> | Parent IDs (nested list with checkboxes only) |
---
Complete Usage Example
@using Syncfusion.Blazor.Lists
<SfListView @ref="ListViewRef"
DataSource="@Items"
ShowCheckBox="true"
ShowHeader="true"
HeaderTitle="Products"
CheckBoxPosition="CheckBoxPosition.Left"
SortOrder="SortOrder.Ascending"
Height="400px"
CssClass="custom-list"
Animation="@ListAnimation">
<ListViewFieldSettings TValue="Product"
Id="Id"
Text="Name"
IconCss="Icon"
Tooltip="Description">
</ListViewFieldSettings>
<ListViewTemplates TValue="Product">
<Template>
@{
var item = context as Product;
<div class="e-list-wrapper e-list-multi-line">
<span class="e-list-item-header">@item.Name</span>
<span class="e-list-content">@item.Description</span>
</div>
}
</Template>
</ListViewTemplates>
<ListViewEvents TValue="Product"
Clicked="@OnItemClicked"
OnActionComplete="@OnActionComplete">
</ListViewEvents>
</SfListView>
<button @onclick="GetSelectedItems">Get Selected Items</button>
@code {
SfListView<Product> ListViewRef;
List<Product> Items = new List<Product>
{
new Product { Id = "1", Name = "Laptop", Description = "High-performance laptop", Icon = "e-icons e-mobile" },
new Product { Id = "2", Name = "Mouse", Description = "Wireless mouse", Icon = "e-icons e-hardware" }
};
public AnimationSettings ListAnimation { get; set; } = new AnimationSettings()
{
Effect = ListViewEffect.Zoom,
Duration = 500,
Easing = "ease"
};
void OnItemClicked(ClickEventArgs<Product> args)
{
Console.WriteLine($"Clicked: {args.Text}");
}
void OnActionComplete(ActionEventsArgs args)
{
Console.WriteLine("Action completed");
}
async Task GetSelectedItems()
{
var selected = await ListViewRef.GetCheckedItemsAsync();
// Process selected.Data, selected.Text, etc.
}
public class Product
{
public string Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Icon { get; set; }
}
}---
Additional Property Examples
Property: Enabled
Disable/enable user interaction with the component:
<SfListView DataSource="@Items"
Enabled="@IsEnabled">
</SfListView>
@code {
bool IsEnabled = true;
void ToggleEnabled()
{
IsEnabled = !IsEnabled;
// Component becomes read-only when Enabled=false
}
}Property: EnablePersistence
Persist checkbox state across page reloads using browser storage:
<SfListView DataSource="@Items"
ShowCheckBox="true"
EnablePersistence="true">
</SfListView>
@* When EnablePersistence is true:
- Checked items are automatically saved to localStorage
- State is restored when the page is refreshed
- User selections persist across sessions *@Property: EnableRtl
Enable right-to-left text direction for languages like Arabic, Hebrew, Urdu:
<SfListView DataSource="@Items"
EnableRtl="@IsRtlEnabled"
ShowHeader="true"
HeaderTitle="قائمة">
</SfListView>
@code {
bool IsRtlEnabled = false;
void SetRtl()
{
IsRtlEnabled = true;
// Text, icons, and layout flow from right to left
}
}Property: HtmlAttributes
Add custom HTML attributes to the component root element:
<SfListView DataSource="@Items"
HtmlAttributes="@CustomAttributes">
</SfListView>
@code {
Dictionary<string, object> CustomAttributes = new Dictionary<string, object>
{
{ "data-testid", "product-list" },
{ "aria-label", "List of Products" },
{ "role", "listbox" }
};
}Property: ID
Set the HTML element ID for the component:
<SfListView ID="productList"
DataSource="@Items">
</SfListView>
@* The rendered element: <div id="productList" ...>...</div>
Useful for CSS selectors and JavaScript interop *@
@code {
void SelectListViaJavaScript()
{
// Can reference: document.getElementById("productList")
}
}Property: ShowIcon
Display icons from data model in list items:
<SfListView DataSource="@Items"
ShowIcon="true">
<ListViewFieldSettings TValue="MenuItem"
Id="Id"
Text="Name"
IconCss="Icon">
</ListViewFieldSettings>
</SfListView>
@code {
List<MenuItem> Items = new List<MenuItem>
{
new MenuItem { Id = "1", Name = "Users", Icon = "e-icons e-people" },
new MenuItem { Id = "2", Name = "Products", Icon = "e-icons e-shopping-cart" }
};
public class MenuItem
{
public string Id { get; set; }
public string Name { get; set; }
public string Icon { get; set; }
}
}Property: Width
Set the component width using CSS length values:
<SfListView DataSource="@Items"
Height="400px"
Width="100%">
</SfListView>
@* Supported values: pixels (300px), percentage (100%), em, rem, etc.
Common patterns:
- Width="100%" - Full width of container
- Width="500px" - Fixed width
- Width="auto" - Auto-size based on content *@---
Event Arguments Reference
Complete documentation of all properties available in event argument classes:
ClickEventArgs<T>
Properties available when handling click events:
| Property | Type | Description |
|---|---|---|
Cancel | bool | Gets or sets a value indicating whether to prevent the current click action on the list item |
Index | int | Gets the index position of the clicked element |
IsChecked | bool | Gets or sets a value that indicates whether the element is checked or not |
IsInteracted | bool | Gets or sets whether the event is triggered by user interaction |
ItemData | T | Gets or sets the data source of the clicked item |
Level | int | Gets or sets the nesting level of the list items |
Text | string | Gets or sets the selected item text |
Example using ClickEventArgs properties:
void OnItemClicked(ClickEventArgs<Product> args)
{
Console.WriteLine($"Item: {args.Text}");
Console.WriteLine($"Index: {args.Index}");
Console.WriteLine($"Checked: {args.IsChecked}");
Console.WriteLine($"Level: {args.Level}");
Console.WriteLine($"User Interaction: {args.IsInteracted}");
// Access full item data
var product = args.ItemData;
Console.WriteLine($"Product ID: {product.Id}");
// Cancel the click action if needed
if (product.Id == "restricted")
{
args.Cancel = true;
}
}ActionEventsArgs
Properties available in action begin/complete events:
| Property | Type | Description |
|---|---|---|
Count | double | Gets or sets the total number of records |
Name | string | Gets whether the event name is 'ActionBegin' or 'ActionComplete' |
Example:
void OnActionBegin(ActionEventsArgs args)
{
if (args.Name == "ActionBegin")
{
Console.WriteLine("Data binding started");
}
}
void OnActionComplete(ActionEventsArgs args)
{
Console.WriteLine($"Total records: {args.Count}");
Console.WriteLine("Data binding completed");
}ActionFailureEventsArgs
Properties available when data action fails (inherits from ActionEventsArgs):
| Property | Type | Description |
|---|---|---|
Error | Exception | Gets or sets the exception error associated with the event |
Count | double | Gets or sets the total number of records (inherited) |
Name | string | Gets the event name (inherited) |
Example:
void OnActionFailure(ActionFailureEventsArgs args)
{
Console.WriteLine($"Error: {args.Error.Message}");
Console.WriteLine($"Error Type: {args.Error.GetType().Name}");
// Log and handle specific error types
if (args.Error is HttpRequestException)
{
Console.WriteLine("Network error occurred");
}
else
{
Console.WriteLine("Server error occurred");
}
}BackEventArgs<T>
Properties available when back button is clicked in nested lists:
| Property | Type | Description |
|---|---|---|
IsInteracted | bool | Gets or sets whether the event is triggered by user interaction |
Level | int | Gets or sets the nesting level of the list items |
Example:
void OnBack(BackEventArgs<Product> args)
{
Console.WriteLine($"Nesting Level: {args.Level}");
Console.WriteLine($"User Interaction: {args.IsInteracted}");
// Handle navigation based on nesting level
if (args.Level == 0)
{
Console.WriteLine("Going back to root level");
}
}---
Navigation Guide
- Getting Started → view
- Data Binding → view
- Templates → view
- Selection & Checkboxes → view
- Filtering & Search → view
- Grouping → view
- Events → view
- Advanced Layouts → view
- Styling → view
- Virtualization → view
- Advanced Patterns → view
Data Binding and Sources in Blazor ListView
Table of Contents
- Overview
- Local Data Arrays
- Field Mapping
- Remote Data with DataManager
- Entity Framework Integration
- Dynamic Data Updates
Overview
ListView supports multiple data sources:
- Local Arrays - Direct C# collections
- DataManager - Remote services (OData, Web API, REST)
- Entity Framework - Database-first or code-first
- Dynamic Collections - Real-time updates with ObservableCollection
Local Data Arrays
Array of JSON Data
Bind simple data with ListViewFieldSettings:
@using Syncfusion.Blazor.Lists
<SfListView DataSource="@Data">
<ListViewFieldSettings TValue="DataModel" Id="Id" Text="Text"></ListViewFieldSettings>
</SfListView>
@code {
public string HeaderTitle = "Listview";
List<DataModel> Data = new List<DataModel>();
protected override void OnInitialized()
{
base.OnInitialized();
Data.Add(new DataModel { Text = "Hennessey Venom", Id = "list-01" });
Data.Add(new DataModel { Text = "Bugatti Chiron", Id = "list-02" });
Data.Add(new DataModel { Text = "Bugatti Veyron Super Sport", Id = "list-03" });
Data.Add(new DataModel { Text = "SSC Ultimate Aero", Id = "list-04" });
Data.Add(new DataModel { Text = "Koenigsegg CCR", Id = "list-05" });
}
public class DataModel
{
public string Id { get; set; }
public string Text { get; set; }
}
}Field Mapping
Use ListViewFieldSettings to map complex data:
<SfListView DataSource="@Products">
<ListViewFieldSettings TValue="Product"
Id="ProductId"
Text="ProductName"
Tooltip="Description"
IconCss="IconClass">
</ListViewFieldSettings>
</SfListView>
@code {
public class Product
{
public int ProductId { get; set; }
public string ProductName { get; set; }
public string Description { get; set; }
public string IconClass { get; set; }
public decimal Price { get; set; }
}
List<Product> Products = new List<Product>
{
new Product
{
ProductId = 1,
ProductName = "Laptop",
Description = "High-performance laptop",
IconClass = "e-icon-device",
Price = 999.99m
},
new Product
{
ProductId = 2,
ProductName = "Mouse",
Description = "Wireless mouse",
IconClass = "e-icon-hardware",
Price = 29.99m
}
};
}Available Field Settings
| Property | Type | Description |
|---|---|---|
Id | string | Map unique identifier |
Text | string | Displayed text field |
Tooltip | string | Hover tooltip field |
IconCss | string | CSS class for icons |
Child | string | Nested items field |
GroupBy | string | Grouping category field |
IsChecked | string | Checkbox state field |
Enabled | string | Enabled/disabled state |
HtmlAttributes | string | HTML attributes field |
Remote Data with DataManager
OData V4 Integration
@using Syncfusion.Blazor.Lists
@using Syncfusion.Blazor.Data
<SfListView HeaderTitle="Products" ShowHeader="true" TValue="Product" Query="@query">
<ListViewFieldSettings TValue="Product" Id="ProductID" Text="ProductName"></ListViewFieldSettings>
<SfDataManager Url="url"
Adaptor="Adaptors.ODataV4Adaptor">
</SfDataManager>
</SfListView>
@code {
public static List<string> column = new List<string>()
{
"ProductID","ProductName"
};
Query query = new Query().From("Products").Select(column).Take(6);
public class Product
{
public int ProductID { get; set; }
public string ProductName { get; set; }
}
}Web API Integration
@using Syncfusion.Blazor.Lists
@using Syncfusion.Blazor.Data
<SfListView TValue="Employee" Query="@query">
<ListViewFieldSettings TValue="Employee" Id="EmployeeID" Text="FirstName"></ListViewFieldSettings>
<SfDataManager Url="url" Adaptor="Adaptors.WebApiAdaptor"></SfDataManager>
</SfListView>
@code {
Query query = new Query().Take(10);
public class Employee
{
public int EmployeeID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
}Entity Framework Integration
Handle CRUD Operations
Create a data access layer for Entity Framework:
using YourApp.Shared.Models;
using Microsoft.EntityFrameworkCore;
public class DataAccessLayer
{
private DataContext db = new DataContext();
// READ
public DbSet<Product> GetAllProducts()
{
try
{
return db.Products;
}
catch
{
throw;
}
}
// CREATE
public void AddProduct(Product product)
{
try
{
db.Products.Add(product);
db.SaveChanges();
}
catch
{
throw;
}
}
// DELETE
public void DeleteProduct(int id)
{
try
{
var product = db.Products.Find(id);
if (product != null)
{
db.Products.Remove(product);
db.SaveChanges();
}
}
catch
{
throw;
}
}
// UPDATE
public void UpdateProduct(Product product)
{
try
{
db.Products.Update(product);
db.SaveChanges();
}
catch
{
throw;
}
}
}```
### Use Entity Framework Data in ListView
@using YourApp.Shared.Models @inject DataAccessLayer DataService
<SfListView DataSource="@Products" ShowHeader="true" HeaderTitle="Products"> <ListViewFieldSettings TValue="Product" Id="ProductId" Text="ProductName"></ListViewFieldSettings> <ListViewTemplates TValue="Product"> <Template> <div class="e-list-wrapper e-list-multi-line"> <span class="e-list-item-header">@((context as Product).ProductName)</span> <span class="e-list-content">Price: $@((context as Product).Price)</span> </div> </Template> </ListViewTemplates> </SfListView>
@code { List<Product> Products = new List<Product>();
protected override async Task OnInitializedAsync() { var dbProducts = DataService.GetAllProducts(); Products = dbProducts.ToList(); } }
### Adding Items from Dialog
@using Syncfusion.Blazor.Popups; @using Syncfusion.Blazor.Buttons;
<button class="e-btn" @onclick="ShowAddDialog">Add Product</button>
<SfDialog @ref="DialogObj" Target="#container" ShowCloseIcon="true" Header="Add Product" @bind-Visible="@DialogVisible" Width="300px"> <DialogTemplates> <Content> <input id="prodName" class="e-input" type="text" placeholder="Product Name" @bind-value="@ProductName" /> <input id="prodPrice" class="e-input" type="number" placeholder="Price" @bind-value="@ProductPrice" /> </Content> </DialogTemplates> <DialogButtons> <DialogButton OnClick="@AddProductAsync" Content="Add" IsPrimary="true" CssClass="e-flat"></DialogButton> </DialogButtons> </SfDialog>
@code { SfDialog DialogObj; bool DialogVisible; string ProductName = ""; decimal ProductPrice = 0;
async Task ShowAddDialog() { DialogVisible = true; await DialogObj.ShowAsync(); }
async Task AddProductAsync() { var newProduct = new Product { ProductName = ProductName, Price = ProductPrice }; DataService.AddProduct(newProduct);
ProductName = ""; ProductPrice = 0; DialogVisible = false;
// Refresh list var dbProducts = DataService.GetAllProducts(); Products = dbProducts.ToList(); StateHasChanged(); } }```
Delete Item
<ListViewTemplates TValue="Product">
<Template>
@{
Product current = (Product)context;
<div class="flex-container">
<span>@current.ProductName</span>
<button class="e-btn e-small" @onclick="@(e => DeleteProduct(current.ProductId))">Delete</button>
</div>
}
</Template>
</ListViewTemplates>
@code {
async Task DeleteProduct(int id)
{
DataService.DeleteProduct(id);
// Refresh list
var dbProducts = DataService.GetAllProducts();
Products = dbProducts.ToList();
StateHasChanged();
}
}Dynamic Data Updates
Using ObservableCollection
For real-time updates, use ObservableCollection:
@using System.Collections.ObjectModel
@using Syncfusion.Blazor.Lists
<SfListView DataSource="@Items">
<ListViewFieldSettings TValue="Item" Id="Id" Text="Name"></ListViewFieldSettings>
</SfListView>
<button class="e-btn" @onclick="AddItem">Add Item</button>
@code {
ObservableCollection<Item> Items = new ObservableCollection<Item>
{
new Item { Id = "1", Name = "Item 1" },
new Item { Id = "2", Name = "Item 2" }
};
void AddItem()
{
Items.Add(new Item { Id = DateTime.Now.Ticks.ToString(), Name = "New Item" });
}
public class Item
{
public string Id { get; set; }
public string Name { get; set; }
}
}Refresh Data
Update the list by reassigning the DataSource:
// After modifying data
Products = newProductList;
StateHasChanged(); // Trigger re-renderAppend Remote Data
<SfListView @ref="ListView" DataSource="@ListData"></SfListView>
<button @onclick="LoadMoreData">Load More</button>
@code {
SfListView<Product> ListView;
List<Product> ListData = new List<Product>();
int pageSize = 10;
int pageNumber = 1;
async Task LoadMoreData()
{
var moreData = await FetchDataAsync(pageNumber++, pageSize);
ListData.AddRange(moreData);
await ListView.RefreshAsync();
}
async Task<List<Product>> FetchDataAsync(int page, int size)
{
// Fetch from API
return await http.GetJsonAsync<List<Product>>($"api/products?page={page}&size={size}");
}
}---
Related Topics:
- Item Selection and Actions - Get selected items from data
- Filtering and Searching - Filter data dynamically
- Grouping and Organization - Group data by category
Events and Navigation in Blazor ListView
Table of Contents
Event Handling
Available Events
The ListView provides lifecycle and interaction events:
<ListViewEvents TValue="Item"
OnActionBegin="@OnActionBegin"
OnActionComplete="@OnActionComplete"
Clicked="@OnClicked">
</ListViewEvents>
@code {
void OnActionBegin(ActionBeginEventArgs<Item> args)
{
// Triggered when action starts
// args.EventType, args.Data available
}
void OnActionComplete(ActionCompleteEventArgs<Item> args)
{
// Triggered when action completes
// Data binding complete event
}
void OnClicked(ClickEventArgs<Item> args)
{
// Triggered when item is clicked
// args.Text, args.Data available
}
}Event Flow
User Action → OnActionBegin → Processing → OnActionComplete
↓
Event CompletionListViewItem Events
Click Event
@using Syncfusion.Blazor.Lists
<SfListView DataSource="@Items">
<ListViewFieldSettings TValue="Item" Id="Id" Text="Text"></ListViewFieldSettings>
<ListViewEvents TValue="Item"
Clicked="@(e => OnItemClicked(e))">
</ListViewEvents>
</SfListView>
<p>Clicked Item: @SelectedItemText</p>
@code {
string SelectedItemText = "";
void OnItemClicked(ClickEventArgs<Item> args)
{
SelectedItemText = args.Text;
Console.WriteLine($"Item clicked: {args.Text}");
// Access item data
var itemData = args.Data;
}
List<Item> Items = new List<Item>
{
new Item { Id = "1", Text = "Option 1" },
new Item { Id = "2", Text = "Option 2" }
};
public class Item
{
public string Id { get; set; }
public string Text { get; set; }
}
}ActionBegin Event - Data Binding
void OnActionBegin(ActionBeginEventArgs<Item> args)
{
// Triggered when ListView starts binding data
if (args.EventType == "initially")
{
Console.WriteLine("ListView initializing...");
}
}ActionComplete Event - Data Binding Complete
void OnActionComplete(ActionCompleteEventArgs<Item> args)
{
// Triggered when data binding completes
Console.WriteLine($"Data bound successfully. Total items: {args.Result?.Count}");
}Navigation Patterns
Navigate on Item Click
@using Syncfusion.Blazor.Lists
@inject NavigationManager NavigationManager
<SfListView DataSource="@Pages">
<ListViewFieldSettings TValue="Page" Id="Id" Text="Name"></ListViewFieldSettings>
<ListViewEvents TValue="Page"
Clicked="@(e => Navigate(e.Data.Url))">
</ListViewEvents>
</SfListView>
@code {
void Navigate(string url)
{
NavigationManager.NavigateTo(url);
}
List<Page> Pages = new List<Page>
{
new Page { Id = "1", Name = "Home", Url = "/" },
new Page { Id = "2", Name = "About", Url = "/about" },
new Page { Id = "3", Name = "Contact", Url = "/contact" }
};
public class Page
{
public string Id { get; set; }
public string Name { get; set; }
public string Url { get; set; }
}
}Detail View Navigation
void OnItemClicked(ClickEventArgs<Product> args)
{
var productId = args.Data.Id;
NavigationManager.NavigateTo($"/product-details/{productId}");
}Hyperlink Integration
Using Anchor Tags in Templates
@using Syncfusion.Blazor.Lists
<SfListView DataSource="@DataSource">
<ListViewFieldSettings TValue="ListDataModel" Id="Id" Text="Name"></ListViewFieldSettings>
<ListViewTemplates TValue="ListDataModel">
<Template>
<a target="_blank" href="@((context as ListDataModel).Url)">
@((context as ListDataModel).Name)
</a>
</Template>
</ListViewTemplates>
</SfListView>
@code {
List<ListDataModel> DataSource = new List<ListDataModel>
{
new ListDataModel { Id = "1", Name = "Google", Url = "url" },
new ListDataModel { Id = "2", Name = "Bing", Url = "url" },
new ListDataModel { Id = "3", Name = "Yahoo", Url = "url" },
new ListDataModel { Id = "4", Name = "Ask.com", Url = "url" }
};
public class ListDataModel
{
public string Id { get; set; }
public string Name { get; set; }
public string Url { get; set; }
}
}Blazor Navigation Links
@using Syncfusion.Blazor.Lists
<SfListView DataSource="@Users" CssClass="e-list-template">
<ListViewFieldSettings TValue="User" Id="Id" Text="Name"></ListViewFieldSettings>
<ListViewTemplates TValue="User">
<Template>
<NavLink href="@($"/user/{((context as User).Id}")">
<div class="e-list-wrapper">
<span class="e-list-content">@((context as User).Name)</span>
</div>
</NavLink>
</Template>
</ListViewTemplates>
</SfListView>
@code {
List<User> Users = new List<User>
{
new User { Id = "1", Name = "User A" },
new User { Id = "2", Name = "User B" }
};
public class User
{
public string Id { get; set; }
public string Name { get; set; }
}
}Combined Navigation and Event Handling
void OnItemClicked(ClickEventArgs<MenuItem> args)
{
// Custom logic
LogUserAction(args.Data.Name);
// Navigate
if (!string.IsNullOrEmpty(args.Data.NavigateUrl))
{
NavigationManager.NavigateTo(args.Data.NavigateUrl);
}
}
void LogUserAction(string itemName)
{
Console.WriteLine($"User selected: {itemName}");
// Send to analytics, etc.
}Complete Event Example
@using Syncfusion.Blazor.Lists
@inject NavigationManager NavigationManager
<div>
<SfListView @ref="ListView"
DataSource="@Items"
ShowHeader="true"
HeaderTitle="Event Demo">
<ListViewFieldSettings TValue="MenuItem" Id="Id" Text="Name"></ListViewFieldSettings>
<ListViewTemplates TValue="MenuItem">
<Template>
<div class="e-list-wrapper" @onclick="@((e) => OnItemClicked((context as MenuItem)))">
<span class="e-list-content">@((context as MenuItem).Name)</span>
</div>
</Template>
</ListViewTemplates>
<ListViewEvents TValue="MenuItem"
OnActionBegin="@OnActionBegin"
OnActionComplete="@OnActionComplete"
Clicked="@OnEventClicked">
</ListViewEvents>
</SfListView>
<!-- Event Log -->
<div style="margin-top: 20px; padding: 12px; background-color: #f5f5f5; border: 1px solid #ddd;">
<h4>Event Log:</h4>
<ul style="list-style: none; padding: 0;">
@foreach (var log in EventLog)
{
<li style="padding: 4px 0; font-size: 12px;">
<span style="color: #999;">[@log.Timestamp]</span> @log.Message
</li>
}
</ul>
</div>
</div>
@code {
SfListView<MenuItem> ListView;
List<MenuItem> Items = new List<MenuItem>();
List<EventLogEntry> EventLog = new List<EventLogEntry>();
private int maxLogs = 10;
protected override void OnInitialized()
{
Items.Add(new MenuItem { Id = "1", Name = "Home", NavigateUrl = "/" });
Items.Add(new MenuItem { Id = "2", Name = "Products", NavigateUrl = "/products" });
Items.Add(new MenuItem { Id = "3", Name = "About", NavigateUrl = "/about" });
Items.Add(new MenuItem { Id = "4", Name = "Contact", NavigateUrl = "/contact" });
}
void OnActionBegin(ActionBeginEventArgs<MenuItem> args)
{
LogEvent("OnActionBegin triggered");
}
void OnActionComplete(ActionCompleteEventArgs<MenuItem> args)
{
LogEvent($"OnActionComplete - Items bound: {Items.Count}");
}
void OnEventClicked(ClickEventArgs<MenuItem> args)
{
LogEvent($"Item clicked: {args.Text}");
}
void OnItemClicked(MenuItem item)
{
LogEvent($"Custom click: {item.Name}");
if (!string.IsNullOrEmpty(item.NavigateUrl))
{
NavigationManager.NavigateTo(item.NavigateUrl);
}
}
void LogEvent(string message)
{
EventLog.Insert(0, new EventLogEntry
{
Timestamp = DateTime.Now.ToString("HH:mm:ss"),
Message = message
});
if (EventLog.Count > maxLogs)
{
EventLog.RemoveAt(EventLog.Count - 1);
}
}
public class MenuItem
{
public string Id { get; set; }
public string Name { get; set; }
public string NavigateUrl { get; set; }
}
public class EventLogEntry
{
public string Timestamp { get; set; }
public string Message { get; set; }
}
}---
Related Topics:
- Item Selection and Actions - Handle selections
- Advanced Patterns - Complex event scenarios
- Templating and Rendering - Event-aware templates
Filtering and Searching in Blazor ListView
Table of Contents
- Real-Time Search Implementation
- Text Input Filtering
- Filter Logic Patterns
- Case-Insensitive Filtering
- Custom Filter Conditions
Real-Time Search Implementation
Basic Search with TextBox
@using Syncfusion.Blazor.Inputs
@using Syncfusion.Blazor.Lists
<div id="container">
<div id="sample">
<SfTextBox Placeholder="Filter" Input="@OnInput"></SfTextBox>
<SfListView ID="list" DataSource="@ListData">
<ListViewFieldSettings TValue="ListDataModel" Id="Id" Text="Text"></ListViewFieldSettings>
</SfListView>
</div>
</div>
@code
{
List<ListDataModel> ListData = new List<ListDataModel>();
List<ListDataModel> DataSource = new List<ListDataModel>() {
new ListDataModel { Text = "Hennessey Venom", Id = "list-01" },
new ListDataModel { Text = "Bugatti Chiron", Id = "list-02" },
new ListDataModel { Text = "Bugatti Veyron Super Sport", Id = "list-03" },
new ListDataModel { Text = "SSC Ultimate Aero", Id = "list-04" },
new ListDataModel { Text = "Koenigsegg CCR", Id = "list-05" },
new ListDataModel { Text = "McLaren F1", Id = "list-06" }
};
protected override void OnInitialized()
{
ListData = DataSource;
}
void OnInput(InputEventArgs eventArgs)
{
ListData = DataSource.FindAll(e => e.Text.ToLower().StartsWith(eventArgs.Value));
}
public class ListDataModel
{
public string Id { get; set; }
public string Text { get; set; }
}
}
<style>
#list {
box-shadow: 0 1px 4px #ddd;
border-bottom: 1px solid #ddd;
}
#sample {
height: 220px;
margin: 0 auto;
display: block;
max-width: 350px;
}
</style>Text Input Filtering
Filter by Multiple Fields
@using Syncfusion.Blazor.Inputs
@using Syncfusion.Blazor.Lists
<div>
<SfTextBox Placeholder="Search products..." Input="@OnSearch"></SfTextBox>
<SfListView DataSource="@FilteredProducts" CssClass="e-list-template">
<ListViewFieldSettings TValue="Product" Id="Id" Text="Name"></ListViewFieldSettings>
<ListViewTemplates TValue="Product">
<Template>
<div class="e-list-wrapper e-list-multi-line">
<span class="e-list-item-header">@((context as Product).Name)</span>
<span class="e-list-content">Category: @((context as Product).Category)</span>
<span class="e-list-content">Price: $@((context as Product).Price)</span>
</div>
</Template>
</ListViewTemplates>
</SfListView>
</div>
@code {
List<Product> FilteredProducts = new List<Product>();
List<Product> AllProducts = new List<Product>
{
new Product { Id = "1", Name = "Laptop", Category = "Electronics", Price = 999.99m },
new Product { Id = "2", Name = "Mouse", Category = "Electronics", Price = 29.99m },
new Product { Id = "3", Name = "Desk Lamp", Category = "Furniture", Price = 49.99m },
new Product { Id = "4", Name = "Monitor Stand", Category = "Furniture", Price = 79.99m },
new Product { Id = "5", Name = "Wireless Keyboard", Category = "Electronics", Price = 89.99m }
};
protected override void OnInitialized()
{
FilteredProducts = AllProducts;
}
void OnSearch(InputEventArgs args)
{
string searchTerm = args.Value?.ToLower() ?? "";
FilteredProducts = AllProducts.Where(p =>
p.Name.ToLower().Contains(searchTerm) ||
p.Category.ToLower().Contains(searchTerm) ||
p.Price.ToString().Contains(searchTerm)
).ToList();
}
public class Product
{
public string Id { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public decimal Price { get; set; }
}
}Filter Logic Patterns
StartsWith Filter
Matches from beginning of text:
void OnInput(InputEventArgs eventArgs)
{
ListData = DataSource.FindAll(e =>
e.Text.ToLower().StartsWith(eventArgs.Value.ToLower())
);
}Contains Filter
Matches anywhere in text:
void OnInput(InputEventArgs eventArgs)
{
ListData = DataSource.FindAll(e =>
e.Text.ToLower().Contains(eventArgs.Value.ToLower())
);
}EndsWith Filter
Matches end of text:
void OnInput(InputEventArgs eventArgs)
{
ListData = DataSource.FindAll(e =>
e.Text.ToLower().EndsWith(eventArgs.Value.ToLower())
);
}Exact Match
void OnInput(InputEventArgs eventArgs)
{
ListData = DataSource.FindAll(e =>
e.Text.Equals(eventArgs.Value, StringComparison.OrdinalIgnoreCase)
);
}Case-Insensitive Filtering
Ensure searches work regardless of uppercase/lowercase:
void OnSearch(InputEventArgs eventArgs)
{
string searchTerm = eventArgs.Value?.ToLower() ?? "";
FilteredProducts = AllProducts.Where(p =>
p.Name.ToLower().Contains(searchTerm) ||
p.Category.ToLower().Contains(searchTerm)
).ToList();
}Accent-Insensitive Filtering
For international characters:
using System.Globalization;
using System.Text;
string NormalizeString(string text)
{
string normalized = text.Normalize(NormalizationForm.FormD);
var sb = new StringBuilder();
foreach (char ch in normalized)
{
if (CharUnicodeInfo.GetUnicodeCategory(ch) != UnicodeCategory.NonSpacingMark)
{
sb.Append(ch);
}
}
return sb.ToString();
}
void OnSearch(InputEventArgs eventArgs)
{
string searchTerm = NormalizeString(eventArgs.Value?.ToLower() ?? "");
FilteredProducts = AllProducts.Where(p =>
NormalizeString(p.Name.ToLower()).Contains(searchTerm)
).ToList();
}Custom Filter Conditions
Filter with Multiple Conditions
@using Syncfusion.Blazor.Inputs
@using Syncfusion.Blazor.Lists
<div>
<div>
<label>Search by Name:</label>
<SfTextBox Input="@(e => OnNameSearch(e))"></SfTextBox>
</div>
<div>
<label>Filter by Category:</label>
<SfDropDownList Items="@Categories" ValueChanged="@((string c) => OnCategoryFilter(c))"></SfDropDownList>
</div>
<div>
<label>Price Range:</label>
<input type="number" placeholder="Min" @onchange="@((ChangeEventArgs e) => minPrice = decimal.Parse(e.Value.ToString()))" />
<input type="number" placeholder="Max" @onchange="@((ChangeEventArgs e) => maxPrice = decimal.Parse(e.Value.ToString()))" />
<button @onclick="ApplyFilters">Filter</button>
</div>
<SfListView DataSource="@FilteredProducts">
<ListViewFieldSettings TValue="Product" Id="Id" Text="Name"></ListViewFieldSettings>
</SfListView>
</div>
@code {
List<Product> FilteredProducts = new List<Product>();
List<Product> AllProducts = new List<Product>
{
new Product { Id = "1", Name = "Laptop", Category = "Electronics", Price = 999.99m },
new Product { Id = "2", Name = "Mouse", Category = "Electronics", Price = 29.99m },
new Product { Id = "3", Name = "Desk", Category = "Furniture", Price = 299.99m }
};
List<string> Categories = new List<string> { "Electronics", "Furniture", "All" };
string searchText = "";
string selectedCategory = "All";
decimal minPrice = 0;
decimal maxPrice = 10000;
protected override void OnInitialized()
{
FilteredProducts = AllProducts;
}
void OnNameSearch(InputEventArgs args)
{
searchText = args.Value?.ToLower() ?? "";
ApplyFilters();
}
void OnCategoryFilter(string category)
{
selectedCategory = category;
ApplyFilters();
}
void ApplyFilters()
{
FilteredProducts = AllProducts.Where(p =>
(string.IsNullOrEmpty(searchText) || p.Name.ToLower().Contains(searchText)) &&
(selectedCategory == "All" || p.Category == selectedCategory) &&
(p.Price >= minPrice && p.Price <= maxPrice)
).ToList();
}
public class Product
{
public string Id { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public decimal Price { get; set; }
}
}Debounced Search (Performance Optimization)
private System.Timers.Timer searchTimer;
private string pendingSearch = "";
protected override void OnInitialized()
{
searchTimer = new System.Timers.Timer(500); // 500ms debounce
searchTimer.Elapsed += async (s, e) =>
{
await InvokeAsync(() => PerformSearch(pendingSearch));
};
searchTimer.AutoReset = false;
}
void OnSearch(InputEventArgs eventArgs)
{
pendingSearch = eventArgs.Value;
searchTimer.Stop();
searchTimer.Start();
}
void PerformSearch(string searchTerm)
{
FilteredProducts = AllProducts.Where(p =>
p.Name.ToLower().Contains(searchTerm.ToLower())
).ToList();
}---
Related Topics:
- Data Binding and Sources - Manage data dynamically
- Item Selection and Actions - Work with filtered selections
- Grouping and Organization - Combine filtering with grouping
Getting Started with Syncfusion Blazor ListView
Table of Contents
- Prerequisites
- Installation Steps
- Setup for Blazor WebAssembly
- Setup for Blazor Web App
- Setup for Blazor Server App
- Initial Component Setup
- Complete Example
Prerequisites
- .NET SDK (latest version)
- Visual Studio 2022, Visual Studio Code, or .NET CLI
- Basic knowledge of Blazor and C#
Check system requirements for Blazor components at Syncfusion documentation.
Installation Steps
1. Create a Blazor Project
Via Visual Studio:
- Create new project → Blazor WebAssembly/Blazor Web App/Blazor Server App
- Or use Syncfusion Blazor Extension for template support
Via .NET CLI:
# WebAssembly
dotnet new blazorwasm -o BlazorApp
cd BlazorApp
# Web App (Auto render mode)
dotnet new blazor -o BlazorWebApp -int Auto
cd BlazorWebApp/BlazorWebApp.Client
# Server
dotnet new blazor -o BlazorApp -int Server
cd BlazorApp2. Install NuGet Packages
Using Package Manager Console:
Install-Package Syncfusion.Blazor.Lists -Version {{ site.releaseversion }}
Install-Package Syncfusion.Blazor.Themes -Version {{ site.releaseversion }}Using .NET CLI:
dotnet add package Syncfusion.Blazor.Lists -Version {{ site.releaseversion }}
dotnet add package Syncfusion.Blazor.Themes -Version {{ site.releaseversion }}
dotnet restore3. Add Import Namespaces
Open ~/_Imports.razor and add:
@using Syncfusion.Blazor
@using Syncfusion.Blazor.Lists4. Register Syncfusion Service
Open ~/Program.cs and register the Syncfusion Blazor service:
using Syncfusion.Blazor;
// WebAssembly
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddSyncfusionBlazor();
await builder.Build().RunAsync();
// Server App
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddSyncfusionBlazor();
var app = builder.Build();
// Web App (register in both server and client Program.cs if using WebAssembly/Auto render mode)
builder.Services.AddSyncfusionBlazor();Setup for Blazor WebAssembly
Add Stylesheet and Script References
In ~/App.razor or ~/Components/App.razor:
<link href="_content/Syncfusion.Blazor.Themes/fluent2.css" rel="stylesheet" />
<!-- Other stylesheets -->
<script src="_content/Syncfusion.Blazor.Core/scripts/syncfusion-blazor.min.js" type="text/javascript"></script>Theme Options
Available themes:
fluent2.css- Fluent 2 Designbootstrap5.css- Bootstrap 5tailwind.css- Tailwind CSSmaterial.css- Material Designfluent.css- Fluent Design
Choose one that matches your design system.
Setup for Blazor Web App
In ~/Components/App.razor, add references using Static Web Assets:
<link href="_content/Syncfusion.Blazor.Themes/fluent2.css" rel="stylesheet" />
<script src="_content/Syncfusion.Blazor.Core/scripts/syncfusion-blazor.min.js" type="text/javascript"></script>Render Mode Configuration:
- If using
Per page/componentinteractivity, add@rendermode InteractiveAuto(orInteractiveServer/InteractiveWebAssembly) at the top of your Razor file - If using
Globalinteractivity, render mode is configured automatically inApp.razor
Setup for Blazor Server App
In ~/_Layout.cshtml or ~/Components/App.razor:
<link href="_content/Syncfusion.Blazor.Themes/fluent2.css" rel="stylesheet" />
<script src="_content/Syncfusion.Blazor.Core/scripts/syncfusion-blazor.min.js" type="text/javascript"></script>Initial Component Setup
Minimal ListView Example
@using Syncfusion.Blazor.Lists
<SfListView DataSource="@ListData">
<ListViewFieldSettings TValue="DataModel" Id="Id" Text="Text"></ListViewFieldSettings>
</SfListView>
@code {
List<DataModel> ListData = new List<DataModel>();
protected override void OnInitialized()
{
ListData.Add(new DataModel { Text = "Item 1", Id = "1" });
ListData.Add(new DataModel { Text = "Item 2", Id = "2" });
ListData.Add(new DataModel { Text = "Item 3", Id = "3" });
}
public class DataModel
{
public string Id { get; set; }
public string Text { get; set; }
}
}ListView with Header
<SfListView DataSource="@ListData"
HeaderTitle="My List"
ShowHeader="true">
<ListViewFieldSettings TValue="DataModel" Id="Id" Text="Text"></ListViewFieldSettings>
</SfListView>Complete Example
@using Syncfusion.Blazor.Lists
<div style="max-width: 400px; margin: 20px;">
<SfListView DataSource="@ListData"
HeaderTitle="Cars"
ShowHeader="true"
Width="100%">
<ListViewFieldSettings TValue="CarModel" Id="Id" Text="Name"></ListViewFieldSettings>
</SfListView>
</div>
@code {
List<CarModel> ListData = new List<CarModel>();
protected override void OnInitialized()
{
base.OnInitialized();
ListData.Add(new CarModel { Name = "Hennessey Venom", Id = "1" });
ListData.Add(new CarModel { Name = "Bugatti Chiron", Id = "2" });
ListData.Add(new CarModel { Name = "Bugatti Veyron Super Sport", Id = "3" });
ListData.Add(new CarModel { Name = "SSC Ultimate Aero", Id = "4" });
ListData.Add(new CarModel { Name = "Koenigsegg CCR", Id = "5" });
}
public class CarModel
{
public string Id { get; set; }
public string Name { get; set; }
}
}---
Next Steps:
- Bind data from sources in Data Binding and Sources
- Customize appearance with Templating and Rendering
- Enable selection in Item Selection and Actions
Grouping and Organization in Blazor ListView
Table of Contents
- Basic Grouping
- Group Header Styling
- Grouped Data Structure
- Hierarchical Grouping
- Advanced Grouping Patterns
Basic Grouping
Group by Single Field
Use the GroupBy property in ListViewFieldSettings:
@using Syncfusion.Blazor.Lists
<SfListView DataSource="@DataSource">
<ListViewFieldSettings TValue="DataModel"
Id="Id"
Text="Text"
GroupBy="Type">
</ListViewFieldSettings>
</SfListView>
@code {
List<DataModel> DataSource = new List<DataModel>()
{
new DataModel { Id = "1", Text = "1", Type = "Odd" },
new DataModel { Id = "2", Text = "2", Type = "Even" },
new DataModel { Id = "3", Text = "3", Type = "Odd" },
new DataModel { Id = "4", Text = "4", Type = "Even" },
new DataModel { Id = "5", Text = "5", Type = "Odd" }
};
public class DataModel
{
public string Id { get; set; }
public string Text { get; set; }
public string Type { get; set; }
}
}Categories Example
@using Syncfusion.Blazor.Lists
<SfListView DataSource="@Products"
ShowHeader="true"
HeaderTitle="Products"
SortOrder="SortOrder.Ascending">
<ListViewFieldSettings TValue="Product"
Id="Id"
Text="Name"
GroupBy="Category">
</ListViewFieldSettings>
</SfListView>
@code {
List<Product> Products = new List<Product>
{
new Product { Id = "1", Name = "Laptop", Category = "Electronics" },
new Product { Id = "2", Name = "Mouse", Category = "Electronics" },
new Product { Id = "3", Name = "Chair", Category = "Furniture" },
new Product { Id = "4", Name = "Desk", Category = "Furniture" },
new Product { Id = "5", Name = "Monitor", Category = "Electronics" }
};
public class Product
{
public string Id { get; set; }
public string Name { get; set; }
public string Category { get; set; }
}
}Group Header Styling
Custom Group Headers
@using Syncfusion.Blazor.Lists
<SfListView DataSource="@DataSource" CssClass="e-list-template">
<ListViewFieldSettings TValue="Item"
Id="Id"
Text="Text"
GroupBy="Category">
</ListViewFieldSettings>
<ListViewTemplates TValue="Item">
<GroupTemplate>
<div style="padding: 12px; background-color: #e0e0e0; font-weight: bold; font-size: 14px;">
📁 @context.Text
</div>
</GroupTemplate>
</ListViewTemplates>
</SfListView>
@code {
List<Item> DataSource = new List<Item>
{
new Item { Id = "1", Text = "Item A", Category = "Category 1" },
new Item { Id = "2", Text = "Item B", Category = "Category 1" },
new Item { Id = "3", Text = "Item C", Category = "Category 2" },
new Item { Id = "4", Text = "Item D", Category = "Category 2" }
};
public class Item
{
public string Id { get; set; }
public string Text { get; set; }
public string Category { get; set; }
}
}
<style>
/* Remove default padding from group header */
.e-list-template .e-list-group-item {
padding: 0 !important;
margin: 0 !important;
}
/* Custom group header styling */
.group-header {
padding: 12px;
background-color: #e0e0e0;
font-weight: bold;
font-size: 14px;
margin: 0;
}
/* Align list items properly */
.e-list-template .e-list-item {
padding: 12px;
}
</style>Styled Groups with Item Counts
<SfListView DataSource="@DataSource" CssClass="custom-grouped-list">
<ListViewFieldSettings TValue="Item"
Id="Id"
Text="Text"
GroupBy="Category">
</ListViewFieldSettings>
<ListViewTemplates TValue="Item">
<GroupTemplate>
@{
var categoryName = context.Text;
var itemsInGroup = context.Items.Count();
}
<div class="styled-group-header">
<span>@categoryName</span>
<span class="item-badge">@itemsInGroup items</span>
</div>
</GroupTemplate>
</ListViewTemplates>
</SfListView>
@code {
List<Item> DataSource = new List<Item>
{
new Item { Id = "1", Text = "Item A", Category = "Category 1" },
new Item { Id = "2", Text = "Item B", Category = "Category 1" },
new Item { Id = "3", Text = "Item C", Category = "Category 2" },
new Item { Id = "4", Text = "Item D", Category = "Category 2" }
};
public class Item
{
public string Id { get; set; }
public string Text { get; set; }
public string Category { get; set; }
}
}
<style>
.custom-grouped-list .e-list-group-item {
padding: 0 !important;
}
.styled-group-header {
padding: 12px 16px;
background-color: #1976d2;
color: white;
font-weight: bold;
display: flex;
justify-content: space-between;
align-items: center;
}
.item-badge {
background-color: rgba(255,255,255,0.3);
padding: 4px 12px;
border-radius: 4px;
font-size: 12px;
}
</style>Grouped Data Structure
Organize Data by Category
public class GroupedViewModel
{
public string CategoryName { get; set; }
public List<Item> Items { get; set; }
}
// Data organization
var groupedData = new List<GroupedViewModel>
{
new GroupedViewModel
{
CategoryName = "Fruits",
Items = new List<Item>
{
new Item { Id = "1", Text = "Apple" },
new Item { Id = "2", Text = "Banana" }
}
},
new GroupedViewModel
{
CategoryName = "Vegetables",
Items = new List<Item>
{
new Item { Id = "3", Text = "Carrot" },
new Item { Id = "4", Text = "Lettuce" }
}
}
};Display Grouped Data
@foreach (var group in GroupedData)
{
<div style="margin-bottom: 20px;">
<h3>@group.CategoryName</h3>
<SfListView DataSource="@group.Items">
<ListViewFieldSettings TValue="Item" Id="Id" Text="Text"></ListViewFieldSettings>
</SfListView>
</div>
}Hierarchical Grouping
Multi-Level Categories
@using Syncfusion.Blazor.Lists
<SfListView DataSource="@ListData" ShowHeader="true" HeaderTitle="Continent">
<ListViewFieldSettings TValue="DataModel"
Id="Id"
Text="Text"
Child="Child">
</ListViewFieldSettings>
</SfListView>
@code {
List<DataModel> ListData = new List<DataModel>();
protected override void OnInitialized()
{
ListData.Add(new DataModel
{
Text = "Asia",
Id = "01",
Child = new List<DataModel>()
{
new DataModel
{
Text = "India",
Id = "1",
Child = new List<DataModel>()
{
new DataModel { Text = "Delhi", Id = "1001" },
new DataModel { Text = "Mumbai", Id = "1002" },
new DataModel { Text = "Bangalore", Id = "1003" }
}
},
new DataModel
{
Text = "China",
Id = "2",
Child = new List<DataModel>()
{
new DataModel { Text = "Beijing", Id = "2001" },
new DataModel { Text = "Shanghai", Id = "2002" }
}
}
}
});
ListData.Add(new DataModel
{
Text = "North America",
Id = "02",
Child = new List<DataModel>()
{
new DataModel
{
Text = "USA",
Id = "3",
Child = new List<DataModel>()
{
new DataModel { Text = "California", Id = "3001" },
new DataModel { Text = "New York", Id = "3002" }
}
}
}
});
}
public class DataModel
{
public string Id { get; set; }
public string Text { get; set; }
public List<DataModel> Child { get; set; }
}
}Advanced Grouping Patterns
Filter Then Group
// Filter products first, then group by category
var filtered = AllProducts.Where(p => p.Price > 50);
var grouped = filtered.GroupBy(p => p.Category)
.Select(g => new { Category = g.Key, Items = g.ToList() })
.ToList();Dynamic Grouping
@using Syncfusion.Blazor.Lists
@using Syncfusion.Blazor.DropDowns
<div style="margin-bottom: 20px;">
<label>Group by: </label>
<SfDropDownList TValue="string"
TItem="GroupOption"
@bind-Value="@CurrentGroupField"
DataSource="@GroupingOptions">
<DropDownListFieldSettings Text="Label" Value="Field"></DropDownListFieldSettings>
</SfDropDownList>
</div>
<SfListView DataSource="@AllProducts" @key="@CurrentGroupField">
<ListViewFieldSettings TValue="Product"
Id="Id"
Text="Name"
GroupBy="@CurrentGroupField">
</ListViewFieldSettings>
</SfListView>
@code {
private List<Product> AllProducts = new List<Product>();
private string CurrentGroupField = "Category";
private List<GroupOption> GroupingOptions = new List<GroupOption>();
protected override void OnInitialized()
{
GroupingOptions = new List<GroupOption>
{
new GroupOption { Label = "Category", Field = "Category" },
new GroupOption { Label = "Brand", Field = "Brand" }
};
AllProducts = new List<Product>
{
new Product { Id = "1", Name = "Laptop", Category = "Electronics", Brand = "Dell" },
new Product { Id = "2", Name = "Mouse", Category = "Electronics", Brand = "Logitech" },
new Product { Id = "3", Name = "Chair", Category = "Furniture", Brand = "Ikea" },
new Product { Id = "4", Name = "Desk", Category = "Furniture", Brand = "Ikea" }
};
}
public class GroupOption
{
public string Label { get; set; } = string.Empty;
public string Field { get; set; } = string.Empty;
}
public class Product
{
public string Id { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty;
public string Category { get; set; } = string.Empty;
public string Brand { get; set; } = string.Empty;
}
}Group with Summary
<SfListView DataSource="@DataSource" CssClass="summary-list">
<ListViewFieldSettings TValue="Item"
Id="Id"
Text="Text"
GroupBy="Category">
</ListViewFieldSettings>
<ListViewTemplates TValue="Item">
<GroupTemplate>
@{
var categoryName = context.Text;
var categoryItems = context.Items.Cast<Item>();
var total = categoryItems.Sum(i => i.Quantity);
}
<div class="summary-header">
<strong>@categoryName</strong>
<span>Total Quantity: @total</span>
</div>
</GroupTemplate>
</ListViewTemplates>
</SfListView>
@code {
List<Item> DataSource = new List<Item>
{
new Item { Id = "1", Text = "Item A", Category = "Electronics", Quantity = 10 },
new Item { Id = "2", Text = "Item B", Category = "Electronics", Quantity = 15 },
new Item { Id = "3", Text = "Item C", Category = "Furniture", Quantity = 5 },
new Item { Id = "4", Text = "Item D", Category = "Furniture", Quantity = 8 }
};
public class Item
{
public string Id { get; set; }
public string Text { get; set; }
public string Category { get; set; }
public int Quantity { get; set; }
}
}---
Related Topics:
- Data Binding and Sources - Prepare data for grouping
- Filtering and Searching - Filter grouped data
- Advanced Patterns - Complex organizational scenarios
Item Selection and Actions in Blazor ListView
Table of Contents
- Getting Selected Items
- GetCheckedItemsAsync Method
- Selection with Checkboxes
- Selection Events
- Custom Template Selection
Getting Selected Items
Retrieve Checked Items
Use the GetCheckedItemsAsync() method to get selected items:
@using Syncfusion.Blazor.Lists
<div style="display: flex;">
<div class="margin">
<SfListView @ref="@SfList"
DataSource="@DataSource"
ShowCheckBox="true">
<ListViewFieldSettings TValue="ListDataModel" Id="Id" Text="Text"></ListViewFieldSettings>
</SfListView>
</div>
<div class="margin">
<div class="padding">
<button class="e-btn" @onclick="@OnSelect">Get Selected Items</button>
</div>
<div class="padding">
<table>
<tr>
<th>Text</th>
<th>Id</th>
</tr>
@foreach (var item in SelectedItems)
{
<tr>
<td>@item.Text</td>
<td>@item.Id</td>
</tr>
}
</table>
</div>
</div>
</div>
@code
{
SfListView<ListDataModel> SfList;
List<ListDataModel> SelectedItems = new List<ListDataModel>();
List<ListDataModel> DataSource = new List<ListDataModel>()
{
new ListDataModel{ Id = "1", Text = "Artwork"},
new ListDataModel{ Id = "2", Text = "Abstract"},
new ListDataModel{ Id = "3", Text = "Modern Painting"},
new ListDataModel{ Id = "4", Text = "Ceramics"},
new ListDataModel{ Id = "5", Text = "Animation Art"},
new ListDataModel{ Id = "6", Text = "Oil Painting"},
};
async void OnSelect()
{
var items = await SfList.GetCheckedItemsAsync();
if (items.Data != null)
{
SelectedItems = items.Data;
this.StateHasChanged();
}
}
public class ListDataModel
{
public string Id { get; set; }
public string Text { get; set; }
}
}
<style>
.margin {
margin: 10px;
width: 300px;
}
.padding {
padding: 10px 0;
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
</style>GetCheckedItemsAsync Method
Return Value Details
The method returns an object with these properties:
| Property | Type | Description |
|---|---|---|
Data | List<T> | Array of selected item data objects |
Text | List<string> | Array of selected item text values |
Index | List<int> | Array of selected item indices (virtualization only) |
ParentId | List<string> | Parent IDs of selected items (nested list only) |
Basic Usage
var checkedItems = await ListViewRef.GetCheckedItemsAsync();
// Access selected data
List<MyDataModel> selectedData = checkedItems.Data;
// Access selected text
List<string> selectedText = checkedItems.Text;
// Access indices (for virtual ListView)
List<int> selectedIndices = checkedItems.Index;Selection with Checkboxes
Enable Checkbox Selection
<SfListView DataSource="@Items"
ShowCheckBox="true"
HeaderTitle="Select Items"
ShowHeader="true">
<ListViewFieldSettings TValue="Item" Id="Id" Text="Name"></ListViewFieldSettings>
</SfListView>
@code {
List<Item> Items = new List<Item>
{
new Item { Id = "1", Name = "Item 1" },
new Item { Id = "2", Name = "Item 2" },
new Item { Id = "3", Name = "Item 3" }
};
public class Item
{
public string Id { get; set; }
public string Name { get; set; }
}
}Multiple Selection Modes
All items selectable:
<SfListView DataSource="@Items" ShowCheckBox="true"></SfListView>Pre-select items using IsChecked field:
@code {
public class Item
{
public string Id { get; set; }
public string Name { get; set; }
public bool IsChecked { get; set; } // Set to true for default selection
}
List<Item> Items = new List<Item>
{
new Item { Id = "1", Name = "Item 1", IsChecked = true },
new Item { Id = "2", Name = "Item 2", IsChecked = false }
};
}Map the field in ListViewFieldSettings:
<ListViewFieldSettings TValue="Item"
Id="Id"
Text="Name"
IsChecked="IsChecked">
</ListViewFieldSettings>Checkbox Position (Left vs Right)
Control checkbox placement using CheckBoxPosition property:
@using Syncfusion.Blazor.Lists
<!-- Checkbox on Left (Default) -->
<h3>Checkbox on Left</h3>
<SfListView DataSource="@Data"
ShowCheckBox="true"
CheckBoxPosition="CheckBoxPosition.Left">
<ListViewFieldSettings TValue="DataModel" Id="Id" Text="Text"></ListViewFieldSettings>
</SfListView>
<!-- Checkbox on Right -->
<h3>Checkbox on Right</h3>
<SfListView DataSource="@Data"
ShowCheckBox="true"
CheckBoxPosition="CheckBoxPosition.Right">
<ListViewFieldSettings TValue="DataModel" Id="Id" Text="Text"></ListViewFieldSettings>
</SfListView>
@code {
private DataModel[] Data = {
new DataModel { Text = "Hennessey Venom", Id = "list-01" },
new DataModel { Text = "Bugatti Chiron", Id = "list-02" },
new DataModel { Text = "Bugatti Veyron Super Sport", Id = "list-03" },
new DataModel { Text = "SSC Ultimate Aero", Id = "list-04" },
new DataModel { Text = "Koenigsegg CCR", Id = "list-05" }
};
public class DataModel
{
public string Text { get; set; }
public string Id { get; set; }
}
}CheckBoxPosition Values:
CheckBoxPosition.Left- Checkbox appears before item text (default)CheckBoxPosition.Right- Checkbox appears after item text
Selection Events
Clicked Event
Respond to item clicks:
@using Syncfusion.Blazor.Lists
<SfListView DataSource="@Items">
<ListViewFieldSettings TValue="Item" Id="Id" Text="Name"></ListViewFieldSettings>
<ListViewEvents TValue="Item"
Clicked="@(args => OnItemClicked(args))">
</ListViewEvents>
</SfListView>
<p>Selected: @SelectedItemText</p>
@code {
string SelectedItemText = "";
void OnItemClicked(ClickEventArgs<Item> args)
{
SelectedItemText = args.Text;
}
List<Item> Items = new List<Item>
{
new Item { Id = "1", Name = "Option 1" },
new Item { Id = "2", Name = "Option 2" }
};
public class Item
{
public string Id { get; set; }
public string Name { get; set; }
}
}OnActionBegin and OnActionComplete Events
<ListViewEvents TValue="Item"
OnActionBegin="@(args => HandleActionBegin(args))"
OnActionComplete="@(args => HandleActionComplete(args))">
</ListViewEvents>
@code {
void HandleActionBegin(ActionBeginEventArgs<Item> args)
{
// Triggered at action start
// args.EventType contains action type
}
void HandleActionComplete(ActionCompleteEventArgs<Item> args)
{
// Triggered when action completes
}
}Custom Template Selection
Selection in Custom Templates
When using custom templates with checkboxes, ensure proper field mapping:
@using Syncfusion.Blazor.Lists
<div id="container">
<div class="sample flex vertical-center">
<div class="padding">
<SfListView @ref="ListView"
DataSource="@DataSource"
ShowCheckBox="true"
CssClass="e-list-template">
<ListViewFieldSettings TValue="ListDataModel"
Id="Id"
Text="Name">
</ListViewFieldSettings>
<ListViewTemplates TValue="ListDataModel">
<Template>
@{
ListDataModel currentData = (ListDataModel)context;
<div class="e-list-wrapper e-list-multi-line e-list-avatar">
<img src="@(currentData.Image)" class="e-avatar e-avatar-circle" />
<span class="e-list-item-header">@currentData.Name</span>
<span class="e-list-content">@currentData.Contact</span>
</div>
}
</Template>
</ListViewTemplates>
</SfListView>
</div>
<div class="padding">
<button class="e-btn" @onclick="GetSelected">Get Selected Items</button>
</div>
</div>
</div>
@code {
SfListView<ListDataModel> ListView;
List<ListDataModel> DataSource = new List<ListDataModel>() {
new ListDataModel { Name = "Nancy", Contact = "(206) 555-985774", Id = "1", Image = "url" },
new ListDataModel { Name = "Janet", Contact = "(206) 555-3412", Id = "2", Image = "url" },
new ListDataModel { Name = "Margaret", Contact = "(206) 555-8122", Id = "4", Image = "url" },
new ListDataModel { Name = "Andrew", Contact = "(206) 555-9482", Id = "5", Image = "url" }
};
async Task GetSelected()
{
var selected = await ListView.GetCheckedItemsAsync();
// Process selected items
}
public class ListDataModel
{
public string Id { get; set; }
public string Name { get; set; }
public string Image { get; set; }
public string Contact { get; set; }
}
}
<style>
#container .e-listview {
box-shadow: 0 1px 4px #ddd;
border-bottom: 1px solid #ddd;
}
.sample {
justify-content: center;
min-height: 280px;
}
.vertical-center {
align-items: center;
}
.padding {
padding: 4px;
}
.flex {
display: flex;
}
</style>Click Handler with Custom Data
<SfListView DataSource="@Items" CssClass="e-list-template">
<ListViewFieldSettings TValue="Item" Id="Id" Text="Name"></ListViewFieldSettings>
<ListViewTemplates TValue="Item">
<Template>
<div class="e-list-wrapper" @onclick="@((e) => SelectItem((Item)context))">
<span class="e-list-content">@((context as Item).Name)</span>
</div>
</Template>
</ListViewTemplates>
</SfListView>
@code {
Item SelectedItem;
void SelectItem(Item item)
{
SelectedItem = item;
}
List<Item> Items = new List<Item>
{
new Item { Id = "1", Name = "Item 1" },
new Item { Id = "2", Name = "Item 2" }
};
public class Item
{
public string Id { get; set; }
public string Name { get; set; }
}
}---
Related Topics:
- Filtering and Searching - Filter selected results
- Data Binding and Sources - Manage data dynamically
- Templating and Rendering - Create selection templates