
Syncfusion Blazor Treegrid
- 232 installs
- 4 repo stars
- Updated July 28, 2026
- syncfusion/blazor-ui-components-skills
Use syncfusion-blazor-treegrid for development tasks
About
syncfusion-blazor-treegrid: A skill for development. This provides functionality for development workflows.
- syncfusion-blazor-treegrid
Syncfusion Blazor Treegrid by the numbers
- 232 all-time installs (skills.sh)
- +13 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #1,651 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Jul 29, 2026 (Skillselion catalog sync)
npx skills add https://github.com/syncfusion/blazor-ui-components-skills --skill syncfusion-blazor-treegridAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 232 |
|---|---|
| repo stars | ★ 4 |
| Last updated | July 28, 2026 |
| Repository | syncfusion/blazor-ui-components-skills ↗ |
What it does
Use syncfusion-blazor-treegrid for development tasks
Files
Implementing Syncfusion Blazor TreeGrid
The Syncfusion Blazor TreeGrid (SfTreeGrid<TValue>) renders hierarchical data in a tabular format with expand/collapse rows. It supports self-referential flat data (IdMapping/ParentIdMapping) and nested child collections, combined with a full suite of grid features including editing, filtering, sorting, virtualization, and export.
When to Use This Skill
- User needs a hierarchical/tree-structured data table in a Blazor app
- User mentions SfTreeGrid, TreeGrid, IdMapping, ParentIdMapping
- User needs parent-child rows with expand/collapse in a grid
- User needs CRUD operations on tree-structured data
- User needs to export, filter, sort, or page hierarchical data
- User needs to bind TreeGrid to a GraphQL API using
GraphQLAdaptor - User is working with organizational charts, task hierarchies, bill of materials, file explorer-style data in grid form
- User migrating from flat DataGrid to hierarchical TreeGrid
- User setting up TreeGrid in a Blazor Web App, WASM, Server, or MAUI project
Trigger keywords: TreeGrid, Tree Grid, SfTreeGrid, hierarchical grid, parent-child grid, IdMapping, ParentIdMapping, tree data table, nested grid rows, Syncfusion Blazor tree, GraphQL TreeGrid, GraphQLAdaptor TreeGrid
---
🔒 Mandatory Key Rules
These rules govern how this skill MUST behave. They are mandatory and must be strictly followed.
1. Purpose and Responsibility
Your responsibility is to interpret any natural‑language user request and provide accurate, complete, and validated information about all supported aspects of the Syncfusion Blazor TreeGrid, including:
- Public APIs
- Properties
- Events
- Features
- Behaviors
2. Accuracy and API Compliance
The Skill MUST:
- Use only officially supported Syncfusion TreeGrid features.
- NEVER invent APIs, methods, properties, events, behaviors, or future features.
- NEVER provide unsupported or hypothetical code samples.
- ALWAYS follow official Syncfusion component design patterns.
If a feature is not supported: clearly state the limitation and suggest a supported alternative when possible.
3. Interpreting Natural-Language Requests
When user requests are incomplete:
- Infer reasonable assumptions using official TreeGrid best practices.
- Fill missing gaps with accurate and relevant information.
- Request clarification only when essential.
4. Handling Unsupported User Requests
If the user asks for an unsupported capability:
- Explicitly state that it is not supported
- Suggest official alternatives or valid workarounds
- NEVER simulate or fabricate impossible functionality
5. Design Pattern Enforcement
The Skill MUST follow Syncfusion official patterns, including:
- Correct component structure (
SfTreeGrid,TreeGridColumn,TreeGridEditSettings,TreeGridEvents, etc.) - Proper async event and API usage
- Valid configuration properties and enums
- Supported data‑binding approaches (self-referential, hierarchical, remote, custom adaptor, GraphQL)
- Real event patterns and names
6. Quality, Completeness & Reliability
The Skill MUST:
- Use only validated and real TreeGrid capabilities
- Provide actionable and implementation‑ready guidance
- Ensure clarity so users can follow without guesswork
- Maintain clean, readable, and professional formatting
7. No-Hallucination Safeguard
The Skill MUST NOT:
- Invent non‑existent APIs or behavior
- Suggest unsupported modes, features, or configuration
- Provide incorrect, misleading, or unverifiable code
- Describe undocumented internal behavior
If unsure: ask for clarification OR clearly state the limitation.
8. Event Name Verification Requirement
CRITICAL: Event names MUST be verified against references/events.md BEFORE providing code examples. All tree grid events MUST be defined inside the <TreeGridEvents> component
Common Mistakes to Avoid:
- ❌
OnSortChange— Does NOT exist. UseSorting,Sortedinstead - ❌
OnFilterChange— Does NOT exist. UseFiltering,Filteredinstead
Rule: ALWAYS cross-reference references/events.md for:
- Exact event names (case-sensitive)
- Event argument types (see Rule 11 for namespace resolution)
- Whether events are cancelable (✅ or ❌)
- When they fire (before/after operation)
9. Read Reference Files Before Writing Code
Before generating any code, identify every feature in the request and read the reference file for each one. The snippets in this file are abbreviated — they omit critical rules and known pitfalls. Reference files are the authoritative source.
⚠️ Read ALL reference files that apply — not just the one most obvious from the query.
10. Namespace and Type Resolution Rules
Rule 1: Always use full namespace qualification to avoid CS0104 "ambiguous reference" errors. Types exist in both Syncfusion.Blazor.TreeGrid and Syncfusion.Blazor.Grids namespaces.
Rule 2: Always include @using Syncfusion.Blazor.Grids; in _Imports.razor or component to prevent CS0103 "missing reference" errors for:
- Event argument types (
ActionEventArgs,RowDataBoundEventArgs,BeforeCopyPasteEventArgs, etc.) - The
Actionenum (Action.Sorting,Action.Save, etc.) - Component classes (
TreeGridPageSettings,TreeGridFilterSettings,TreeGridSelectionSettings, etc.) - Event handler support classes
Rule 3: The following event arg types belong to Syncfusion.Blazor.TreeGrid — add @using Syncfusion.Blazor.TreeGrid; (NOT Syncfusion.Blazor.Grids):
RowExpandingEventArgs<TValue>,RowExpandedEventArgs<TValue>RowCollapsingEventArgs<TValue>,RowCollapsedEventArgs<TValue>CheckBoxChangeEventArgs<TValue>
Type Reference:
| Type | Namespace | Example |
|---|---|---|
| FilterType | TreeGrid | Syncfusion.Blazor.TreeGrid.FilterType.Excel |
| EditMode | TreeGrid | Syncfusion.Blazor.TreeGrid.EditMode.Row |
| CopyHierarchyType | TreeGrid | Syncfusion.Blazor.TreeGrid.CopyHierarchyType.Both |
| Action | Grids | Syncfusion.Blazor.Grids.Action.Save |
| TextAlign | Grids | Syncfusion.Blazor.Grids.TextAlign.Right |
| ColumnType | Grids | Syncfusion.Blazor.Grids.ColumnType.Date |
| EditType | Grids | Syncfusion.Blazor.Grids.EditType.DatePickerEdit |
| SelectionMode | Grids | Syncfusion.Blazor.Grids.SelectionMode.Row |
| SelectionType | Grids | Syncfusion.Blazor.Grids.SelectionType.Multiple |
| ClipMode | Grids | Syncfusion.Blazor.Grids.ClipMode.Ellipsis |
| GridLine | Grids | Syncfusion.Blazor.Grids.GridLine.Horizontal |
| AggregateType | Grids | Syncfusion.Blazor.Grids.AggregateType.Sum |
| CellSelectionMode | Grids | Syncfusion.Blazor.Grids.CellSelectionMode.Box |
---
Component Overview
<SfTreeGrid DataSource="@TreeData"
IdMapping="TaskId"
ParentIdMapping="ParentId"
TreeColumnIndex="1"
AllowSorting="true"
AllowFiltering="true"
AllowPaging="true">
<TreeGridColumns>
<TreeGridColumn Field="TaskId" HeaderText="ID" Width="80" IsPrimaryKey="true" />
<TreeGridColumn Field="TaskName" HeaderText="Task Name" Width="200" />
<TreeGridColumn Field="Duration" HeaderText="Duration" Width="100" />
<TreeGridColumn Field="Progress" HeaderText="Progress" Width="100" />
</TreeGridColumns>
</SfTreeGrid>Key concepts:
IdMapping— property name that uniquely identifies each rowParentIdMapping— property name pointing to the parent row's ID (null/0 = root)TreeColumnIndex— column index that shows the expand/collapse icon (0-based)
---
Navigation Guide
Setup & Getting Started
- Read: references/getting-started.md
- NuGet install,
_Imports.razor,Program.cs, theme/script setup, basic grid,IdMapping/ParentIdMapping/TreeColumnIndex, expand-collapse all,OnActionFailure
Data Binding
- Read: references/data-binding.md
- Self-referential flat data, hierarchical nested children, remote URL/OData/Web API,
SfDataManager, load on demand - Read: references/custom-binding.md
DataAdaptoroverride,Read/ReadAsync, Insert/Update/Delete, paging & sorting support, self-referential only- Read: references/graphql.md
- Hot Chocolate server,
GraphQLAdaptor,GraphQLAdaptorOptions,DataManagerRequestInput, CRUD mutations, cascading delete, CORS
Columns & Cells
- Read: references/columns.md
ColumnType,Format,TextAlign, frozen, reorder, resize, chooser, stacked headers, column menu, foreign key- Read: references/cell.md
QueryCellInfo,CustomAttributes,ClipMode,GridLines, tooltips
Sorting, Filtering & Searching
- Read: references/sorting.md
AllowSorting, multi-sort,SortComparer,SortColumnAsync,ClearSortingAsync, hierarchy preserved- Read: references/filtering.md
AllowFiltering,FilterType(FilterBar/Menu/Excel/CheckBox), hierarchy modes, operators,FilterByColumnAsync. ⚠️ See filtering.md forFilterTemplaterules- Read: references/searching.md
- Toolbar Search,
SearchAsync,GridSearchSettings, hierarchy modes, highlight/clear
Editing
- Read: references/editing.md
- Edit modes (Cell/Row/Dialog/Batch), edit types, command column, validation, template editing, EF Core. ⚠️ See editing.md for
ValidationRules. Always add@using Syncfusion.Blazor.Gridswhen using<TreeGridEvents>
Rows & Selection
- Read: references/rows.md
RowDataBound, row/detail template, drag-and-drop, row height, row spanning- Read: references/selection.md
- Row/cell/both modes, checkbox column, toggle, drag select, programmatic selection, touch
Paging & Virtualization
- Read: references/paging.md
AllowPaging,TreeGridPageSettings,PageSize, pager position/template, programmatic navigation- Read: references/virtualization.md
EnableVirtualization,EnableColumnVirtualization, vs. paging, limitations
Toolbar, Menus & Templates
- Read: references/toolbar.md
- Built-in & custom items,
EnableToolbarItemsAsync,OnToolbarClick - Read: references/context-menu.md
ContextMenuItems, custom items,ContextMenuItemClicked, conditional show/hide- Read: references/templates.md
- Column/header/row/detail/toolbar templates, loading indicator
Exporting & Scrolling
- Read: references/exporting.md
ExportToExcelAsync,ExportToPdfAsync,PrintAsync, custom data/headers, themes- Read: references/scrolling.md
- Frozen rows/columns (
FrozenRows,IsFrozen,FreezeDirection),AllowFreezeLineMoving,EnableStickyHeader,ScrollIntoViewAsync
Advanced Features
- Read: references/aggregates.md
TreeGridAggregateColumn(Field+Typerequired),AggregateType,FooterTemplate,ShowChildSummary, custom LINQ, page-scope limitation- Read: references/clipboard.md
- Copy (Ctrl+C/Ctrl+Shift+H),
CopyAsync, paste (Box+Batch),CopyHierarchyMode,BeforeCopyPaste - Read: references/autofill.md
EnableAutoFill+ Cell/Box selection + Batch edit, limitations- Read: references/adaptive-layout.md
EnableAdaptiveUI, full-screen dialogs, vertical row mode- Read: references/state-management.md
EnablePersistence, persisted properties, manual state methods
Events
- Read: references/events.md
TreeGridEvents<TValue>,OnActionBegin/OnActionComplete,RowDataBound,QueryCellInfo, cancel actions
---
Quick Start Example
1. Install NuGet: Syncfusion.Blazor.TreeGrid
2. Register in `_Imports.razor`:
@using Syncfusion.Blazor
@using Syncfusion.Blazor.TreeGrid3. Add CSS in `wwwroot/index.html` or `App.razor`:
<link href="_content/Syncfusion.Blazor.Themes/material.css" rel="stylesheet" />4. Add to `Program.cs`:
builder.Services.AddSyncfusionBlazor();5. Minimal component:
@using Syncfusion.Blazor.TreeGrid
<SfTreeGrid DataSource="@TreeData" IdMapping="Id" ParentIdMapping="ParentId" TreeColumnIndex="1">
<TreeGridColumns>
<TreeGridColumn Field="Id" HeaderText="ID" Width="80" IsPrimaryKey="true" />
<TreeGridColumn Field="Name" HeaderText="Name" Width="200" />
<TreeGridColumn Field="Status" HeaderText="Status" Width="120" />
</TreeGridColumns>
</SfTreeGrid>
@code {
public class TaskItem
{
public int Id { get; set; }
public int? ParentId { get; set; }
public string Name { get; set; }
public string Status { get; set; }
}
private List<TaskItem> TreeData = new()
{
new TaskItem { Id = 1, ParentId = null, Name = "Project Alpha", Status = "In Progress" },
new TaskItem { Id = 2, ParentId = 1, Name = "Design Phase", Status = "Done" },
new TaskItem { Id = 3, ParentId = 1, Name = "Development", Status = "In Progress" },
new TaskItem { Id = 4, ParentId = 3, Name = "Backend API", Status = "Pending" },
};
}---
Common Patterns
Full-Featured TreeGrid (Sorting + Filtering + Paging + Editing)
<SfTreeGrid @ref="TreeGridRef"
DataSource="@TreeData"
IdMapping="Id"
ParentIdMapping="ParentId"
TreeColumnIndex="1"
AllowSorting="true"
AllowFiltering="true"
AllowPaging="true"
Toolbar="@(new List<string> { "Add", "Edit", "Delete", "Update", "Cancel" })">
<TreeGridEditSettings AllowAdding="true"
AllowEditing="true"
AllowDeleting="true"
Mode="Syncfusion.Blazor.TreeGrid.EditMode.Row" />
<TreeGridPageSettings PageSize="10" />
<TreeGridColumns>
<TreeGridColumn Field="Id" IsPrimaryKey="true" Visible="false" />
<TreeGridColumn Field="Name" HeaderText="Task" Width="220" />
<TreeGridColumn Field="Duration" HeaderText="Days" Width="100" />
<TreeGridColumn Field="Progress" HeaderText="%" Width="100" />
</TreeGridColumns>
</SfTreeGrid>
@code {
private SfTreeGrid<TaskItem> TreeGridRef;
// ... data and model
}Excel & PDF Export
<SfTreeGrid @ref="TreeGridRef" AllowExcelExport="true" AllowPdfExport="true"
Toolbar="@(new List<string> { "ExcelExport", "PdfExport" })">
<TreeGridEvents TValue="TaskItem" OnToolbarClick="ToolbarClickHandler" />
...
</SfTreeGrid>
@code {
private SfTreeGrid<TaskItem> TreeGridRef;
private async Task ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args)
{
if (args.Item.Id.Contains("excelexport"))
await TreeGridRef.ExportToExcelAsync();
else if (args.Item.Id.Contains("pdfexport"))
await TreeGridRef.ExportToPdfAsync();
}
}Adaptive Layout in Syncfusion Blazor TreeGrid
Table of Contents
---
Overview
The TreeGrid UI is redesigned for small screens — filter, sort, and edit dialogs render as full-screen overlays, and rows can render vertically for better mobile usability.
---
Enable Adaptive UI
Set EnableAdaptiveUI="true" to activate mobile-optimized dialogs:
@using Syncfusion.Blazor.TreeGrid
@using Syncfusion.Blazor.Grids
<div class="e-mobile-layout">
<div class="e-mobile-content">
<SfTreeGrid DataSource="@TreeData"
IdMapping="TaskID"
ParentIdMapping="ParentID"
TreeColumnIndex="1"
EnableAdaptiveUI="true"
AllowSorting="true"
AllowFiltering="true"
AllowPaging="true"
Height="100%"
Width="100%"
Toolbar="@(new List<string> { "Add", "Edit", "Delete", "Cancel", "Update", "Search" })">
<TreeGridFilterSettings Type="FilterType.Excel" />
<TreeGridPageSettings PageSize="5" PageSizeMode="PageSizeMode.Root" />
<TreeGridEditSettings AllowAdding="true"
AllowEditing="true"
AllowDeleting="true"
Mode="EditMode.Dialog" />
<TreeGridColumns>
<TreeGridColumn Field="TaskID" HeaderText="Task ID" IsPrimaryKey="true" Width="135" TextAlign="TextAlign.Right"
ValidationRules="@(new ValidationRules { Required = true, Number = true })" />
<TreeGridColumn Field="TaskName" HeaderText="Task Name" Width="280"
ValidationRules="@(new ValidationRules { Required = true })" />
<TreeGridColumn Field="Duration" HeaderText="Duration" Width="140" TextAlign="TextAlign.Right" />
<TreeGridColumn Field="Progress" HeaderText="Progress" Width="145"
EditType="EditType.DropDownEdit" />
</TreeGridColumns>
</SfTreeGrid>
</div>
</div>
@code {
private List<SelfReferenceData> TreeData { get; set; }
protected override void OnInitialized()
{
TreeData = SelfReferenceData.GetTree().Take(30).ToList();
}
}What changes with `EnableAdaptiveUI="true"`:
- Filter dialog opens full-screen instead of inline/popup
- Sort dialog opens full-screen
- Edit dialog opens full-screen (Dialog mode recommended)
- Toolbar collapses to a mobile-friendly layout
- Pager adapts to mobile screen size
---
Recommended CSS Setup
Wrap the grid in a mobile container for best results:
.e-mobile-layout {
position: relative;
width: 360px;
height: 640px;
margin: auto;
border: 2px solid black;
}
.e-mobile-content {
overflow: auto;
height: 100%;
width: 100%;
}Thee-adaptive-demoande-biggerCSS classes help trigger the Syncfusion mobile breakpoints.
---
Key Notes
| Setting | Recommendation |
|---|---|
| Edit mode | Use EditMode.Dialog with adaptive UI for best experience |
| Filter type | FilterType.Excel works well in full-screen adaptive dialog |
| Height/Width | Set to 100% to fill the mobile container |
PageSizeMode | Use PageSizeMode.Root to page only root-level rows |
---
Aggregates in Syncfusion Blazor TreeGrid
Required namespace: Include@using Syncfusion.Blazor.Grids;forAggregateType(Grids namespace) and aggregate event arguments.
Namespace note:AggregateTypebelongs toSyncfusion.Blazor.Grids, notSyncfusion.Blazor.TreeGrid. Always qualify it asSyncfusion.Blazor.Grids.AggregateType.Sum(or.Average,.Min,.Max, etc.) to avoid CS0104 ambiguity errors.
Aggregate values are displayed in the TreeGrid footer and in parent row footer for child row aggregate values. It is configured through TreeGridAggregateColumn. The Field and Type are the minimum properties required to represent an aggregate column.
By default, the aggregate value can be displayed in the TreeGrid footer, and footer of child rows. To show the aggregate value in one of the cells, use the FooterTemplate.
Table of Contents
- Built-in Aggregate Types
- Aggregate Row Layout Rule
- Footer Aggregate
- How to Format Aggregate Value
- Child Summary Aggregates
- Custom Aggregates
- Limitations
---
Built-in Aggregate Types
The aggregate type should be specified in the Type property to configure an aggregate column.
| Type | Description |
|---|---|
Syncfusion.Blazor.Grids.AggregateType.Sum | Total of all values |
Syncfusion.Blazor.Grids.AggregateType.Average | Mean value |
Syncfusion.Blazor.Grids.AggregateType.Min | Minimum value |
Syncfusion.Blazor.Grids.AggregateType.Max | Maximum value |
Syncfusion.Blazor.Grids.AggregateType.Count | Number of records |
Syncfusion.Blazor.Grids.AggregateType.TrueCount | Count of true values in a boolean column |
Syncfusion.Blazor.Grids.AggregateType.FalseCount | Count of false values in a boolean column |
---
Aggregate Row Layout Rule
Key principle: Control aggregate rows by how fields are distributed across `<TreeGridAggregate>` blocks.
- Similar-field aggregates in SAME row → Place multiple
<TreeGridAggregateColumn>entries on different fields within a single<TreeGridAggregate>block - Example: Sum(Duration) + TrueCount(Approved) → One
<TreeGridAggregate>block with both columns - Result: Single footer row showing both aggregates side-by-side
- Same-field aggregates in SEPARATE rows → For multiple aggregates on the same field (e.g., Min + Max on Duration), use separate
<TreeGridAggregate>blocks - Example: Min(Duration) in Row 1, Max(Duration) in Row 2 → Two
<TreeGridAggregate>blocks, each with one column - Result: Two separate footer rows, one for each aggregate
Example structure:
<TreeGridAggregates>
<!-- Row 1: Different fields in same row -->
<TreeGridAggregate ShowChildSummary="false">
<TreeGridAggregateColumns>
<TreeGridAggregateColumn Field="Duration" Type="Sum" />
<TreeGridAggregateColumn Field="Approved" Type="TrueCount" />
</TreeGridAggregateColumns>
</TreeGridAggregate>
<!-- Row 2: Same field, separate aggregate -->
<TreeGridAggregate ShowChildSummary="false">
<TreeGridAggregateColumns>
<TreeGridAggregateColumn Field="Duration" Type="Average" />
</TreeGridAggregateColumns>
</TreeGridAggregate>
</TreeGridAggregates>---
Footer Aggregate
Footer aggregate value is calculated for all the rows and is displayed in the footer cells. Use the FooterTemplate to render the aggregate value in footer cells.
The aggregate values must be accessed inside the template using their corresponding AggregateType.@using TreeGridComponent.Data;
@using Syncfusion.Blazor.TreeGrid;
<SfTreeGrid DataSource="@TreeGridData" IdMapping="TaskId" ParentIdMapping="ParentId" AllowPaging="true" TreeColumnIndex="1">
<TreeGridAggregates>
<TreeGridAggregate ShowChildSummary="false">
<TreeGridAggregateColumns>
<TreeGridAggregateColumn Field="Duration" Type="Syncfusion.Blazor.Grids.AggregateType.Sum" Format="C2">
<FooterTemplate>
@{
var sumvalue = (context as Syncfusion.Blazor.Grids.AggregateTemplateContext);
<div>
<p>Sum: @sumvalue.Sum</p>
</div>
}
</FooterTemplate>
</TreeGridAggregateColumn>
<TreeGridAggregateColumn Field="Approved" Type="Syncfusion.Blazor.Grids.AggregateType.TrueCount" Format="C2">
<FooterTemplate>
@{
var truecount = (context as Syncfusion.Blazor.Grids.AggregateTemplateContext);
<div>
<p>Approved: @truecount.TrueCount</p>
</div>
}
</FooterTemplate>
</TreeGridAggregateColumn>
</TreeGridAggregateColumns>
</TreeGridAggregate>
</TreeGridAggregates>
<TreeGridColumns>
<TreeGridColumn Field="TaskId" HeaderText="Task ID" Width="80" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right"></TreeGridColumn>
<TreeGridColumn Field="TaskName" HeaderText="Task Name" Width="100"></TreeGridColumn>
<TreeGridColumn Field="Duration" HeaderText="Duration" Width="100" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right"></TreeGridColumn>
<TreeGridColumn Field="Progress" HeaderText="Progress" Width="100" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right"></TreeGridColumn>
<TreeGridColumn Field="Approved" HeaderText="Approved" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Center" DisplayAsCheckBox="true" Width="100">
</TreeGridColumn>
</TreeGridColumns>
</SfTreeGrid>
@code {
public List<TreeData> TreeGridData { get; set; }
public Syncfusion.Blazor.Grids.AggregateTemplateContext model = new Syncfusion.Blazor.Grids.AggregateTemplateContext();
protected override void OnInitialized()
{
this.TreeGridData = TreeData.GetSelfDataSource().ToList();
}
}Model class:
namespace TreeGridComponent.Data {
public class TreeData
{
public int TaskId { get; set; }
public string TaskName { get; set; }
public DateTime? StartDate { get; set; }
public int? Duration { get; set; }
public int? Progress { get; set; }
public bool Approved { get; set; }
public int? ParentId { get; set; }
public static List<TreeData> GetSelfDataSource()
{
List<TreeData> TreeDataCollection = new List<TreeData>();
TreeDataCollection.Add(new TreeData() { TaskId = 1, TaskName = "Parent Task 1", Duration = 10, Progress = 70, Approved = true, ParentId = null });
TreeDataCollection.Add(new TreeData() { TaskId = 2, TaskName = "Child task 1", Duration = 4, Progress = 80, Approved = false, ParentId = 1 });
TreeDataCollection.Add(new TreeData() { TaskId = 3, TaskName = "Child Task 2", Duration = 5, Progress = 65, Approved = true, ParentId = 2 });
TreeDataCollection.Add(new TreeData() { TaskId = 4, TaskName = "Child task 3", Duration = 6, Approved = false, Progress = 77, ParentId = 3 });
TreeDataCollection.Add(new TreeData() { TaskId = 5, TaskName = "Parent Task 2", Duration = 10, Progress = 70, Approved = true, ParentId = null });
TreeDataCollection.Add(new TreeData() { TaskId = 6, TaskName = "Child task 1", Duration = 4, Progress = 80, Approved = false, ParentId = 5 });
TreeDataCollection.Add(new TreeData() { TaskId = 7, TaskName = "Child Task 2", Duration = 5, Progress = 65, Approved = true, ParentId = 5 });
TreeDataCollection.Add(new TreeData() { TaskId = 8, TaskName = "Child task 3", Duration = 6, Progress = 77, Approved = false, ParentId = 5 });
TreeDataCollection.Add(new TreeData() { TaskId = 9, TaskName = "Child task 4", Duration = 6, Progress = 77, Approved = true, ParentId = 5 });
return TreeDataCollection;
}
}
}---
How to Format Aggregate Value
The aggregate value result can be formatted by using the Format property on TreeGridAggregateColumn.
@using TreeGridComponent.Data;
@using Syncfusion.Blazor.TreeGrid;
<SfTreeGrid DataSource="@TreeGridData" IdMapping="TaskId" ParentIdMapping="ParentId" AllowPaging="true" TreeColumnIndex="1">
<TreeGridAggregates>
<TreeGridAggregate ShowChildSummary="false">
<TreeGridAggregateColumns>
<TreeGridAggregateColumn Field="Duration" Type="Syncfusion.Blazor.Grids.AggregateType.Sum" Format="C2">
<FooterTemplate>
@{
var sumvalue = (context as Syncfusion.Blazor.Grids.AggregateTemplateContext);
<div>
<p>Sum: @sumvalue.Sum</p>
</div>
}
</FooterTemplate>
</TreeGridAggregateColumn>
</TreeGridAggregateColumns>
</TreeGridAggregate>
</TreeGridAggregates>
<TreeGridColumns>
<TreeGridColumn Field="TaskId" HeaderText="Task ID" Width="80" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right"></TreeGridColumn>
<TreeGridColumn Field="TaskName" HeaderText="Task Name" Width="100"></TreeGridColumn>
<TreeGridColumn Field="Duration" HeaderText="Duration" Width="100" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right"></TreeGridColumn>
<TreeGridColumn Field="Progress" HeaderText="Progress" Width="100" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right"></TreeGridColumn>
<TreeGridColumn Field="Approved" HeaderText="Approved" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Center" DisplayAsCheckBox="true" Width="100">
</TreeGridColumn>
</TreeGridColumns>
</SfTreeGrid>
@code {
public List<TreeData> TreeGridData { get; set; }
public Syncfusion.Blazor.Grids.AggregateTemplateContext model = new Syncfusion.Blazor.Grids.AggregateTemplateContext();
protected override void OnInitialized()
{
this.TreeGridData = TreeData.GetSelfDataSource().ToList();
}
}Use theFormatproperty (e.g.,Format="C2") onTreeGridAggregateColumnto format aggregate values — do not use.ToString()formatting inside the template.
---
Child Summary Aggregates
By default, the aggregate values are shown for all rows including child rows in the footer. Set ShowChildSummary="true" on <TreeGridAggregate> to display aggregate subtotals in the parent row footer for their child data.
ShowChildSummary | Behavior |
|---|---|
false (default) | Aggregate shown only in the grid footer for all records |
true | Aggregate also shown in each parent row's summary row, calculated from that parent's children |
<SfTreeGrid DataSource="@TreeGridData" IdMapping="TaskId" ParentIdMapping="ParentId" TreeColumnIndex="1">
<TreeGridAggregates>
<TreeGridAggregate ShowChildSummary="true">
<TreeGridAggregateColumns>
<TreeGridAggregateColumn Field="Duration" Type="Syncfusion.Blazor.Grids.AggregateType.Sum" Format="C2">
<FooterTemplate>
@{
var sumvalue = (context as Syncfusion.Blazor.Grids.AggregateTemplateContext);
<div>
<p>Sum: @sumvalue.Sum</p>
</div>
}
</FooterTemplate>
</TreeGridAggregateColumn>
</TreeGridAggregateColumns>
</TreeGridAggregate>
</TreeGridAggregates>
<TreeGridColumns>
<TreeGridColumn Field="TaskId" HeaderText="Task ID" Width="80" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<TreeGridColumn Field="TaskName" HeaderText="Task Name" Width="160" />
<TreeGridColumn Field="Duration" HeaderText="Duration" Width="100" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<TreeGridColumn Field="Progress" HeaderText="Progress" Width="100" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
</TreeGridColumns>
</SfTreeGrid>---
Custom Aggregates
Custom aggregates enable calculations beyond the built-in types. Implement custom logic directly in the FooterTemplate using LINQ and helper methods with safe component references.
Key pattern:
- Use
@ref="TreeGrid"(nullable type) to safely reference the TreeGrid component - Use
GetCurrentViewRecords()to access currently visible records (pagination-aware) - Implement helper methods with try-catch for error handling
- Place all aggregates in a single
<TreeGridAggregate>block for single-row footer display - Handle null TreeGrid reference with fallback to
TreeGridData
Complete working example with dynamic category filtering:
@page "/custom-aggregates"
@using Syncfusion.Blazor.TreeGrid
@using Syncfusion.Blazor.Grids
@using Syncfusion.Blazor.DropDowns
@using System.Linq
<SfTreeGrid @ref="TreeGrid"
DataSource="@TreeGridData"
IdMapping="ID"
ParentIdMapping="ParentID"
Height="400"
TreeColumnIndex="1">
<TreeGridAggregates>
<!-- Single Row: Multiple custom aggregates with dropdown filter -->
<TreeGridAggregate ShowChildSummary="false">
<TreeGridAggregateColumns>
<!-- Custom 1: Sum by Category -->
<TreeGridAggregateColumn Field="TotalPrice"
Type="Syncfusion.Blazor.Grids.AggregateType.Sum">
<FooterTemplate>
@{
var _ = (context as Syncfusion.Blazor.Grids.AggregateTemplateContext);
<span>
@SumForSelectedCategory().ToString("C2")
</span>
}
</FooterTemplate>
</TreeGridAggregateColumn>
<!-- Custom 2: Category Dropdown Filter -->
<TreeGridAggregateColumn Field="ShipmentCategory"
Type="Syncfusion.Blazor.Grids.AggregateType.Sum">
<FooterTemplate>
@{
var _ = (context as Syncfusion.Blazor.Grids.AggregateTemplateContext);
<div class="treeDropDown">
<span style="margin-right: 5px;">Category: </span>
<span>
<SfDropDownList TValue="string" TItem="string"
DataSource="@Categories"
@bind-Value="SelectedCategory" />
</span>
</div>
}
</FooterTemplate>
</TreeGridAggregateColumn>
</TreeGridAggregateColumns>
</TreeGridAggregate>
</TreeGridAggregates>
<TreeGridColumns>
<TreeGridColumn Field="ShipID" HeaderText="Ship ID" Width="80" Visible="false" IsPrimaryKey="true" TextAlign="TextAlign.Right"></TreeGridColumn>
<TreeGridColumn Field="Name" HeaderText="Orders" Width="120" ClipMode="ClipMode.EllipsisWithTooltip"></TreeGridColumn>
<TreeGridColumn Field="ShipmentCategory" HeaderText="Category" Width="130"></TreeGridColumn>
<TreeGridColumn Field="OrderDate" HeaderText="Ordered Date" Format="d" Type="ColumnType.Date" Width="130" TextAlign="TextAlign.Right"></TreeGridColumn>
<TreeGridColumn Field="ShippedDate" HeaderText="Shipped Date" Format="d" Type="ColumnType.Date" Width="130" TextAlign="TextAlign.Right"></TreeGridColumn>
<TreeGridColumn Field="Units" HeaderText="Units" Width="80" TextAlign="TextAlign.Right"></TreeGridColumn>
<TreeGridColumn Field="UnitPrice" HeaderText="Unit Price" Format="c2" Width="90" TextAlign="TextAlign.Right"></TreeGridColumn>
<TreeGridColumn Field="TotalPrice" HeaderText="Total Price" Format="C" Width="100" TextAlign="TextAlign.Right"></TreeGridColumn>
</TreeGridColumns>
</SfTreeGrid>
<style>
.treeDropDown {
display: flex;
align-items: baseline;
}
</style>
@code {
private SfTreeGrid<ShipmentData>? TreeGrid;
private string SelectedCategory = "Seafood";
private readonly List<string> Categories = new()
{
"Seafood",
"Dairy",
"Edible"
};
public List<ShipmentData> TreeGridData { get; set; } = new();
protected override void OnInitialized()
{
TreeGridData = ShipmentData.GetShipmentData().ToList();
}
/// <summary>
/// Safe helper: Sum only the visible (current view) rows that match the selected category.
/// Handles null TreeGrid reference with fallback to TreeGridData.
/// </summary>
private decimal SumForSelectedCategory()
{
IEnumerable<ShipmentData> view;
if (TreeGrid != null)
{
var records = TreeGrid.GetCurrentViewRecords();
view = records.OfType<ShipmentData>();
}
else
{
view = TreeGridData;
}
return view.Where(x => x.ShipmentCategory == SelectedCategory).Sum(x => (decimal)(x.TotalPrice ?? 0));
}
public class ShipmentData
{
public int? ID { get; set; }
public int? ShipID { get; set; }
public string? Name { get; set; }
public int? Units { get; set; }
public string? Category { get; set; }
public int? UnitPrice { get; set; }
public int? Price { get; set; }
public int? TotalPrice { get; set; }
public string? ShipmentCategory { get; set; }
public DateTime? ShippedDate { get; set; } = null;
public DateTime? OrderDate { get; set; } = null;
public string? OrderReached { get; set; } = null;
public int? ParentID { get; set; }
private static void CalculateTotalPrices(List<ShipmentData> data)
{
var parents = data.Where(d => d.ParentID == null).ToList();
foreach (var parent in parents)
{
var children = data.Where(d => d.ParentID == parent.ID).ToList();
parent.TotalPrice = children.Sum(c => c.Price ?? 0);
}
foreach (var item in data.Where(d => d.ParentID != null))
{
item.TotalPrice = item.Price;
}
}
public static List<ShipmentData> GetShipmentData()
{
List<ShipmentData> DataCollection = new()
{
new ShipmentData { ID = 0, Name = "Order 1", ParentID = null },
new ShipmentData { ID = 1, ShipID = 4789, Name = "Mackerel", Category = "Seafood", Units = 25, UnitPrice = 12, Price = 300, OrderDate = new DateTime(2025, 3, 3), ShippedDate = new DateTime(2025, 3, 10), ShipmentCategory = "Seafood", OrderReached = "No", ParentID = 0 },
new ShipmentData { ID = 2, ShipID = 4833, Name = "Herrings", Category = "Seafood", Units = 28, UnitPrice = 11, Price = 308, OrderDate = new DateTime(2025, 8, 5), ShippedDate = new DateTime(2025, 8, 15), ShipmentCategory = "Seafood", OrderReached = "Yes", ParentID = 0 },
new ShipmentData { ID = 3, ShipID = 4567, Name = "Preserved Olives", Category = "Edible", Units = 22, UnitPrice = 9, Price = 198, OrderDate = new DateTime(2025, 6, 10), ShippedDate = new DateTime(2025, 6, 17), ShipmentCategory = "Edible", OrderReached = "Yes", ParentID = 0 },
new ShipmentData { ID = 4, ShipID = 4899, Name = "Sweet corn", Category = "Edible", Units = 27, UnitPrice = 7, Price = 189, OrderDate = new DateTime(2025, 7, 12), ShippedDate = new DateTime(2025, 7, 19), ShipmentCategory = "Edible", OrderReached = "No", ParentID = 0 },
new ShipmentData { ID = 5, Name = "Order 2", ParentID = null },
new ShipmentData { ID = 6, ShipID = 5678, Name = "Tilapias", Category = "Seafood", Units = 24, UnitPrice = 15, Price = 360, OrderDate = new DateTime(2025, 2, 5), ShippedDate = new DateTime(2025, 2, 12), ShipmentCategory = "Seafood", OrderReached = "Yes", ParentID = 5 },
new ShipmentData { ID = 7, ShipID = 5990, Name = "White Shrimp", Category = "Seafood", Units = 30, UnitPrice = 7, Price = 210, OrderDate = new DateTime(2025, 5, 22), ShippedDate = new DateTime(2025, 5, 29), ShipmentCategory = "Seafood", OrderReached = "Yes", ParentID = 5 },
new ShipmentData { ID = 8, ShipID = 5476, Name = "Fresh Cheese", Category = "Dairy", Units = 26, UnitPrice = 12, Price = 312, OrderDate = new DateTime(2025, 6, 8), ShippedDate = new DateTime(2025, 6, 15), ShipmentCategory = "Dairy", OrderReached = "Yes", ParentID = 5 },
new ShipmentData { ID = 9, ShipID = 5788, Name = "Blue Veined Cheese", Category = "Dairy", Units = 29, UnitPrice = 15, Price = 435, OrderDate = new DateTime(2025, 7, 10), ShippedDate = new DateTime(2025, 7, 17), ShipmentCategory = "Dairy", OrderReached = "No", ParentID = 5 },
new ShipmentData { ID = 10, ShipID = 5896, Name = "Butter", Category = "Dairy", Units = 21, UnitPrice = 9, Price = 189, OrderDate = new DateTime(2025, 9, 18), ShippedDate = new DateTime(2025, 9, 25), ShipmentCategory = "Dairy", OrderReached = "Yes", ParentID = 5 }
};
CalculateTotalPrices(DataCollection);
return DataCollection;
}
}
}---
Limitations
- By default, Footer Aggregate (total aggregate) is shown only for the current page records and not for the entire DataSource. To aggregate across all page records, set an adaptor in
SfDataManager.
---
AutoFill in Syncfusion Blazor TreeGrid
Table of Contents
---
Overview
AutoFill allows copying selected cell values to adjacent cells by dragging the autofill icon — similar to Excel's fill-handle behavior. After selecting a range of cells, a handle appears at the bottom-right corner; drag it up or down to fill adjacent cells with the same values.
---
Enable AutoFill
Set EnableAutoFill="true" on the grid. Three conditions must all be met for the feature to activate:
@using Syncfusion.Blazor.TreeGrid
<SfTreeGrid DataSource="@TreeData"
IdMapping="TaskId"
ParentIdMapping="ParentId"
TreeColumnIndex="1"
EnableAutoFill="true"
AllowPaging="true"
Toolbar="@(new List<string> { "Add", "Delete", "Update", "Cancel" })">
<TreeGridPageSettings PageSize="5" />
<!-- Condition 2: Cell selection in Box mode -->
<TreeGridSelectionSettings
Type="Syncfusion.Blazor.Grids.SelectionType.Multiple"
Mode="Syncfusion.Blazor.Grids.SelectionMode.Cell"
CellSelectionMode="Syncfusion.Blazor.Grids.CellSelectionMode.Box" />
<!-- Condition 3: Batch editing mode -->
<TreeGridEditSettings
AllowAdding="true"
AllowEditing="true"
AllowDeleting="true"
Mode="EditMode.Batch" />
<TreeGridColumns>
<TreeGridColumn Field="TaskId" HeaderText="Task ID" Width="80" IsPrimaryKey="true" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<TreeGridColumn Field="TaskName" HeaderText="Task Name" Width="155" />
<TreeGridColumn Field="StartDate" HeaderText="Start Date" Width="100" Format="d"
Type="Syncfusion.Blazor.Grids.ColumnType.Date"
EditType="Syncfusion.Blazor.Grids.EditType.DatePickerEdit"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<TreeGridColumn Field="Duration" HeaderText="Duration" Width="80" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<TreeGridColumn Field="Progress" HeaderText="Progress" Width="80" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<TreeGridColumn Field="Priority" HeaderText="Priority" Width="80" />
</TreeGridColumns>
</SfTreeGrid>
@code {
public List<BusinessObject> TreeData { get; set; }
protected override void OnInitialized()
{
TreeData = BusinessObject.GetSelfDataSource();
}
}---
Requirements
All three conditions must be satisfied simultaneously for the autofill handle to appear:
| # | Requirement | Configuration |
|---|---|---|
| 1 | AutoFill enabled | EnableAutoFill="true" on SfTreeGrid |
| 2 | Cell selection in Box mode | Mode="Cell" + CellSelectionMode="Box" on TreeGridSelectionSettings |
| 3 | Batch editing enabled | Mode="EditMode.Batch" on TreeGridEditSettings |
If any one of these is missing, the autofill icon will not appear on cell selection.
---
Limitations
| Scenario | Behavior |
|---|---|
| String value → Number column | Cell displays as NaN — string is not parsed to a number |
| String value → Date column | Cell displays as empty — string is not parsed to a date |
| Sequential/linear series | Not supported — values are copied as-is, no increment (1, 2, 3...) |
| Edit mode other than Batch | AutoFill does not work — Batch editing is mandatory |
---
Cell Customization in Syncfusion Blazor TreeGrid
Namespace note:ClipModeandTextAlignbelong toSyncfusion.Blazor.Grids, notSyncfusion.Blazor.TreeGrid. Always qualify them asSyncfusion.Blazor.Grids.ClipMode.EllipsisandSyncfusion.Blazor.Grids.TextAlign.Rightto avoid CS0104 ambiguity errors.
Table of Contents
---
HTML Content in Cells
By default, HTML tags are encoded (displayed as plain text). To render actual HTML content in cells and headers, set DisableHtmlEncode="true" on the column to disable the encoding. This allows HTML tags to be rendered as actual HTML instead of plain text.
@using Syncfusion.Blazor.TreeGrid
<SfTreeGrid IdMapping="TaskId" DataSource="@TreeGridData" ParentIdMapping="ParentId" TreeColumnIndex="1">
<TreeGridColumns>
<TreeGridColumn Field="TaskId" HeaderText="<span> Task ID </span>" Width="80" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" DisableHtmlEncode="true" />
<TreeGridColumn Field="TaskName" HeaderText="<span> Task Name </span>" Width="160" DisableHtmlEncode="true" />
<TreeGridColumn Field="Duration" HeaderText="<span> Duration </span>" Width="100" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" DisableHtmlEncode="true" />
<TreeGridColumn Field="Progress" HeaderText="<span> Progress </span>" Width="100" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" DisableHtmlEncode="true" />
</TreeGridColumns>
</SfTreeGrid>
@code {
public List<BusinessObject> TreeGridData { get; set; }
protected override void OnInitialized()
{
this.TreeGridData = new List<BusinessObject>
{
new BusinessObject { TaskId = 1, TaskName = "Parent Task 1", StartDate = new DateTime(2017, 10, 23), Duration = 10, Progress = 70, ParentId = null },
new BusinessObject { TaskId = 2, TaskName = "Child task 1", StartDate = new DateTime(2017, 10, 23), Duration = 4, Progress = 80, ParentId = 1 },
new BusinessObject { TaskId = 3, TaskName = "Child Task 2", StartDate = new DateTime(2017, 10, 24), Duration = 5, Progress = 65, ParentId = 2 },
new BusinessObject { TaskId = 4, TaskName = "Child task 3", StartDate = new DateTime(2017, 10, 25), Duration = 6, Progress = 77, ParentId = 3 }
};
}
}
public class BusinessObject
{
public int TaskId { get; set; }
public string TaskName { get; set; }
public DateTime? StartDate { get; set; }
public int? Duration { get; set; }
public int? Progress { get; set; }
public int? ParentId { get; set; }
}⚠️ Only use with trusted data. Enabling this on user-supplied content can expose XSS vulnerabilities.
---
Customize Cell Styles
The appearance of cells can be customized by using the QueryCellInfo event. The QueryCellInfo event triggers for every cell. In that event handler, you can get QueryCellInfoEventArgs that contains the details of the cell.
@using Syncfusion.Blazor.TreeGrid
<SfTreeGrid DataSource="@TreeGridData" IdMapping="TaskId" ParentIdMapping="ParentId" TreeColumnIndex="1">
<TreeGridEvents QueryCellInfo="OnQueryCellInfo" TValue="TreeData" />
<TreeGridColumns>
<TreeGridColumn Field="TaskId" HeaderText="Task ID" Width="90" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<TreeGridColumn Field="TaskName" HeaderText="Task Name" Width="100" />
<TreeGridColumn Field="Duration" HeaderText="Duration" Width="100" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<TreeGridColumn Field="Progress" HeaderText="Progress" Width="100" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<TreeGridColumn Field="Priority" HeaderText="Priority" Width="100" />
</TreeGridColumns>
</SfTreeGrid>
<style>
.intro {
background-color: #336c12;
color: white;
}
.intro1 {
background-color: #7b2b1d;
color: white;
}
</style>
@code {
public List<TreeData> TreeGridData { get; set; }
protected override void OnInitialized()
{
this.TreeGridData = new List<TreeData>
{
new TreeData { TaskId = 1, TaskName = "Parent Task 1", Duration = 10, Progress = 70, Priority = "Critical", ParentId = null },
new TreeData { TaskId = 2, TaskName = "Child task 1", Duration = 4, Progress = 80, Priority = "Low", ParentId = 1 },
new TreeData { TaskId = 3, TaskName = "Child Task 2", Duration = 5, Progress = 65, Priority = "Critical", ParentId = 2 },
new TreeData { TaskId = 4, TaskName = "Child task 3", Duration = 6, Progress = 77, Priority = "High", ParentId = 3 },
new TreeData { TaskId = 5, TaskName = "Parent Task 2", Duration = 10, Progress = 70, Priority = "Critical", ParentId = null },
new TreeData { TaskId = 6, TaskName = "Child task 1", Duration = 4, Progress = 80, Priority = "Critical", ParentId = 5 },
new TreeData { TaskId = 7, TaskName = "Child Task 2", Duration = 5, Progress = 65, Priority = "Low", ParentId = 5 },
new TreeData { TaskId = 8, TaskName = "Child task 3", Duration = 6, Progress = 77, Priority = "High", ParentId = 5 },
new TreeData { TaskId = 9, TaskName = "Child task 4", Duration = 6, Progress = 77, Priority = "Low", ParentId = 5 }
};
}
private void OnQueryCellInfo(QueryCellInfoEventArgs<TreeData> args)
{
if (args.Column.Field == "Progress" && args.Data.Progress > 70 && args.Data.Progress <= 100)
{
args.Cell.AddClass(new[] { "intro" });
}
else if (args.Column.Field == "Progress" && args.Data.Progress > 20)
{
args.Cell.AddClass(new[] { "intro1" });
}
}
}
public class TreeData
{
public int TaskId { get; set; }
public string TaskName { get; set; }
public DateTime? StartDate { get; set; }
public int? Duration { get; set; }
public int? Progress { get; set; }
public string Priority { get; set; }
public int? ParentId { get; set; }
}---
Auto Wrap
The auto wrap allows the cell content of the tree grid to wrap to the next line when it exceeds the boundary of the cell width. The cell content wrapping works based on the position of white space between words. To enable auto wrap, set the AllowTextWrap property to true.
Note: When a column width is not specified, then auto wrap of columns will be adjusted with respect to the tree grid's width.
@using Syncfusion.Blazor.TreeGrid
<SfTreeGrid DataSource="@TreeGridData" IdMapping="TaskId" ParentIdMapping="ParentId" TreeColumnIndex="1" AllowTextWrap="true">
<TreeGridColumns>
<TreeGridColumn Field="TaskId" HeaderText="Task ID" Width="80" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<TreeGridColumn Field="TaskName" HeaderText="Task Name" Width="100" />
<TreeGridColumn Field="StartDate" HeaderText="Start Date" Format="yMd" Type="Syncfusion.Blazor.Grids.ColumnType.Date" Width="100" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<TreeGridColumn Field="Duration" HeaderText="Duration" Width="100" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<TreeGridColumn Field="Progress" HeaderText="Progress" Width="100" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<TreeGridColumn Field="Priority" HeaderText="Priority" Width="100" />
</TreeGridColumns>
</SfTreeGrid>
@code {
public List<BusinessObject> TreeGridData { get; set; }
protected override void OnInitialized()
{
this.TreeGridData = new List<BusinessObject>
{
new BusinessObject { TaskId = 1, TaskName = "Parent Task 1", StartDate = new DateTime(2017, 10, 23), Duration = 10, Progress = 70, Priority = "Critical", ParentId = null },
new BusinessObject { TaskId = 2, TaskName = "Child task 1", StartDate = new DateTime(2017, 10, 23), Duration = 4, Progress = 80, Priority = "Low", ParentId = 1 },
new BusinessObject { TaskId = 3, TaskName = "Child Task 2", StartDate = new DateTime(2017, 10, 24), Duration = 5, Progress = 65, Priority = "Critical", ParentId = 2 },
new BusinessObject { TaskId = 4, TaskName = "Child task 3", StartDate = new DateTime(2017, 10, 25), Duration = 6, Progress = 77, Priority = "High", ParentId = 3 }
};
}
}
public class BusinessObject
{
public int TaskId { get; set; }
public string TaskName { get; set; }
public DateTime? StartDate { get; set; }
public int? Duration { get; set; }
public int? Progress { get; set; }
public string Priority { get; set; }
public int? ParentId { get; set; }
}---
Grid Lines
The GridLines property controls cell border display and can be defined by the GridLines property.
The available modes of grid lines are:
| Modes | Actions |
|---|---|
| Both | Displays both the horizontal and vertical grid lines |
| None | No grid lines are displayed |
| Horizontal | Displays the horizontal grid lines only |
| Vertical | Displays the vertical grid lines only |
| Default | Displays grid lines based on the theme |
@using Syncfusion.Blazor.TreeGrid
<SfTreeGrid IdMapping="TaskId" ParentIdMapping="ParentId" DataSource="@TreeGridData" TreeColumnIndex="1" GridLines="Syncfusion.Blazor.Grids.GridLine.None">
<TreeGridColumns>
<TreeGridColumn Field="TaskId" HeaderText="Task ID" Width="80" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<TreeGridColumn Field="TaskName" HeaderText="Task Name" Width="100" />
<TreeGridColumn Field="StartDate" HeaderText="Start Date" Format="yMd" Type="Syncfusion.Blazor.Grids.ColumnType.Date" Width="100" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<TreeGridColumn Field="Duration" HeaderText="Duration" Width="100" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<TreeGridColumn Field="Progress" HeaderText="Progress" Width="100" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<TreeGridColumn Field="Priority" HeaderText="Priority" Width="100" />
</TreeGridColumns>
</SfTreeGrid>
@code {
public List<BusinessObject> TreeGridData { get; set; }
protected override void OnInitialized()
{
this.TreeGridData = new List<BusinessObject>
{
new BusinessObject { TaskId = 1, TaskName = "Parent Task 1", StartDate = new DateTime(2017, 10, 23), Duration = 10, Progress = 70, Priority = "Critical", ParentId = null },
new BusinessObject { TaskId = 2, TaskName = "Child task 1", StartDate = new DateTime(2017, 10, 23), Duration = 4, Progress = 80, Priority = "Low", ParentId = 1 },
new BusinessObject { TaskId = 3, TaskName = "Child Task 2", StartDate = new DateTime(2017, 10, 24), Duration = 5, Progress = 65, Priority = "Critical", ParentId = 2 },
new BusinessObject { TaskId = 4, TaskName = "Child task 3", StartDate = new DateTime(2017, 10, 25), Duration = 6, Progress = 77, Priority = "High", ParentId = 3 }
};
}
}
public class BusinessObject
{
public int TaskId { get; set; }
public string TaskName { get; set; }
public DateTime? StartDate { get; set; }
public int? Duration { get; set; }
public int? Progress { get; set; }
public string Priority { get; set; }
public int? ParentId { get; set; }
}Note: By default, the tree grid renders with Default mode.
---
Clip Mode
The clip mode provides options to display its overflow cell content and it can be defined by the ClipMode property.
There are three types of ClipMode:
- Clip: Truncates the cell content when it overflows its area.
- Ellipsis: Displays ellipsis when the cell content overflows its area.
- EllipsisWithTooltip: Displays ellipsis when the cell content overflows its area, also it will display the tooltip while hover on ellipsis is applied.
@using Syncfusion.Blazor.TreeGrid
<SfTreeGrid IdMapping="TaskId" ParentIdMapping="ParentId" DataSource="@TreeGridData" TreeColumnIndex="1">
<TreeGridColumns>
<TreeGridColumn Field="TaskId" HeaderText="Task ID" Width="80" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<TreeGridColumn Field="TaskName" HeaderText="Task Name" Width="100" ClipMode="Syncfusion.Blazor.Grids.ClipMode.EllipsisWithTooltip" />
<TreeGridColumn Field="StartDate" HeaderText="Start Date" ClipMode="Syncfusion.Blazor.Grids.ClipMode.Ellipsis" Width="100" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<TreeGridColumn Field="Duration" HeaderText="Duration" Width="100" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<TreeGridColumn Field="Progress" HeaderText="Progress" Width="100" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<TreeGridColumn Field="Priority" HeaderText="Priority" Width="60" ClipMode="Syncfusion.Blazor.Grids.ClipMode.Clip" />
</TreeGridColumns>
</SfTreeGrid>
@code {
public List<BusinessObject> TreeGridData { get; set; }
protected override void OnInitialized()
{
this.TreeGridData = new List<BusinessObject>
{
new BusinessObject { TaskId = 1, TaskName = "Parent Task 1", StartDate = new DateTime(2017, 10, 23), Duration = 10, Progress = 70, Priority = "Critical", ParentId = null },
new BusinessObject { TaskId = 2, TaskName = "Child task 1", StartDate = new DateTime(2017, 10, 23), Duration = 4, Progress = 80, Priority = "Low", ParentId = 1 },
new BusinessObject { TaskId = 3, TaskName = "Child Task 2", StartDate = new DateTime(2017, 10, 24), Duration = 5, Progress = 65, Priority = "Critical", ParentId = 2 },
new BusinessObject { TaskId = 4, TaskName = "Child task 3", StartDate = new DateTime(2017, 10, 25), Duration = 6, Progress = 77, Priority = "High", ParentId = 3 }
};
}
}
public class BusinessObject
{
public int TaskId { get; set; }
public string TaskName { get; set; }
public DateTime? StartDate { get; set; }
public int? Duration { get; set; }
public int? Progress { get; set; }
public string Priority { get; set; }
public int? ParentId { get; set; }
}Note: By default, ClipMode value is Ellipsis.---
Clipboard in Syncfusion Blazor TreeGrid
Namespace note:CopyHierarchyTypeandBeforeCopyPasteEventArgsbelong toSyncfusion.Blazor.TreeGrid. Always qualify them asSyncfusion.Blazor.TreeGrid.CopyHierarchyType.BothandSyncfusion.Blazor.TreeGrid.BeforeCopyPasteEventArgsto avoid CS0104 ambiguity errors when both Grid and TreeGrid namespaces are in scope.
Table of Contents
---
Keyboard Shortcuts
The TreeGrid supports built-in clipboard operations with no additional configuration:
| Shortcut | Action |
|---|---|
Ctrl + C | Copy selected rows or cells to clipboard |
Ctrl + Shift + H | Copy selected rows or cells with column headers |
Ctrl + V | Paste copied cell values into selected cells |
---
Copy via External Button
Use CopyAsync to trigger copy programmatically. Pass true to include column headers:
@using Syncfusion.Blazor.TreeGrid
@using Syncfusion.Blazor.Buttons
<SfButton OnClick="Copy">Copy</SfButton>
<SfButton OnClick="CopyWithHeader">Copy With Header</SfButton>
<SfTreeGrid @ref="TreeGrid"
DataSource="@TreeData"
IdMapping="TaskId"
ParentIdMapping="ParentId"
TreeColumnIndex="1">
<TreeGridColumns>
<TreeGridColumn Field="TaskId" HeaderText="Task ID" Width="80" IsPrimaryKey="true" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<TreeGridColumn Field="TaskName" HeaderText="Task Name" Width="155" />
<TreeGridColumn Field="StartDate" HeaderText="Start Date" Width="100" Format="d" Type="Syncfusion.Blazor.Grids.ColumnType.Date" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<TreeGridColumn Field="Duration" HeaderText="Duration" Width="80" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<TreeGridColumn Field="Progress" HeaderText="Progress" Width="80" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
</TreeGridColumns>
</SfTreeGrid>
@code {
SfTreeGrid<BusinessObject> TreeGrid;
public List<BusinessObject> TreeData { get; set; }
protected override void OnInitialized()
{
TreeData = BusinessObject.GetSelfDataSource();
}
public async Task Copy()
{
await TreeGrid.CopyAsync();
}
public async Task CopyWithHeader()
{
await TreeGrid.CopyAsync(withHeader: true);
}
}---
Copy Hierarchy Modes
CopyHierarchyMode controls which related rows are included in the clipboard output when a record is copied:
<SfTreeGrid DataSource="@TreeData"
IdMapping="TaskId"
ParentIdMapping="ParentId"
TreeColumnIndex="1"
CopyHierarchyMode="CopyHierarchyType.Both">
...
</SfTreeGrid>| Value | Behavior |
|---|---|
Parent (default) | Selected records + their parent records |
Child | Selected records + their child records |
Both | Selected records + both parent and child records |
None | Only the selected records — no related rows |
Dynamic change via dropdown:
@using Syncfusion.Blazor.TreeGrid;
@using Syncfusion.Blazor.DropDowns;
<SfDropDownList TValue="string" TItem="CopyModeOption"
DataSource="@CopyModes"
@bind-Value="@CopyMode">
<DropDownListEvents TValue="string" TItem="CopyModeOption"
ValueChange="OnTypeChange" />
<DropDownListFieldSettings Text="Text" Value="Value" />
</SfDropDownList>
<SfTreeGrid @ref="TreeGrid" CopyHierarchyMode="@CopyType" DataSource="@TreeData" IdMapping="TaskId" ParentIdMapping="ParentId" TreeColumnIndex="1">
<TreeGridColumns>
<TreeGridColumn Field="TaskId" HeaderText="Task ID" Width="60" TextAlign="TextAlign.Right"></TreeGridColumn>
<TreeGridColumn Field="TaskName" HeaderText="Task Name" Width="80"></TreeGridColumn>
<TreeGridColumn Field="StartDate" HeaderText="Start Date" Format="d" Type=ColumnType.Date Width="90" TextAlign="TextAlign.Right"></TreeGridColumn>
<TreeGridColumn Field="Duration" HeaderText="Duration" Width="80" TextAlign="TextAlign.Right"></TreeGridColumn>
<TreeGridColumn Field="Progress" HeaderText="Progress" Width="80"></TreeGridColumn>
</TreeGridColumns>
</SfTreeGrid>
@code {
SfTreeGrid<BusinessObject> TreeGrid;
public string CopyMode { get; set; } = "Parent";
public CopyHierarchyType CopyType { get; set; } = CopyHierarchyType.Parent;
public List<BusinessObject> TreeData { get; set; }
public List<CopyModeOption> CopyModes { get; set; } = new List<CopyModeOption>();
public class CopyModeOption
{
public string Value { get; set; }
public string Text { get; set; }
}
protected override void OnInitialized()
{
this.TreeData = BusinessObject.GetSelfDataSource().ToList();
this.CopyModes.Add(new CopyModeOption() { Value = "Parent", Text = "Parent" });
this.CopyModes.Add(new CopyModeOption() { Value = "Child", Text = "Child" });
this.CopyModes.Add(new CopyModeOption() { Value = "Both", Text = "Both" });
this.CopyModes.Add(new CopyModeOption() { Value = "None", Text = "None" });
}
private void OnTypeChange(Syncfusion.Blazor.DropDowns.ChangeEventArgs<string, CopyModeOption> args)
{
if (args.Value == "Parent")
{
CopyType = CopyHierarchyType.Parent;
}
else if (args.Value == "Child")
{
CopyType = CopyHierarchyType.Child;
}
else if (args.Value == "Both")
{
CopyType = CopyHierarchyType.Both;
}
else if (args.Value == "None")
{
CopyType = CopyHierarchyType.None;
}
}
public class BusinessObject
{
public int TaskId { get; set; }
public string TaskName { get; set; }
public DateTime? StartDate { get; set; }
public int? Duration { get; set; }
public int? Progress { get; set; }
public string Priority { get; set; }
public int? ParentId { get; set; }
public static List<BusinessObject> GetSelfDataSource()
{
List<BusinessObject> BusinessObjectCollection = new List<BusinessObject>();
BusinessObjectCollection.Add(new BusinessObject() { TaskId = 1, TaskName = "Parent Task 1", StartDate = new DateTime(2017, 10, 23), Duration = 10, Progress = 70, Priority = "Critical", ParentId = null });
BusinessObjectCollection.Add(new BusinessObject() { TaskId = 2, TaskName = "Child task 1", StartDate = new DateTime(2017, 10, 23), Duration = 12, Progress = 80, Priority = "Low", ParentId = 1 });
BusinessObjectCollection.Add(new BusinessObject() { TaskId = 3, TaskName = "Child Task 2", StartDate = new DateTime(2017, 10, 24), Duration = 5, Progress = 65, Priority = "Critical", ParentId = 2 });
BusinessObjectCollection.Add(new BusinessObject() { TaskId = 4, TaskName = "Child task 3", StartDate = new DateTime(2017, 10, 25), Duration = 6, Priority = "High", Progress = 77, ParentId = 3 });
BusinessObjectCollection.Add(new BusinessObject() { TaskId = 5, TaskName = "Child Task 5", StartDate = new DateTime(2017, 10, 26), Duration = 9, Progress = 25, ParentId = 4, Priority = "Normal" });
BusinessObjectCollection.Add(new BusinessObject() { TaskId = 6, TaskName = "Child Task 6", StartDate = new DateTime(2017, 10, 27), Duration = 9, Progress = 7, ParentId = 5, Priority = "Normal" });
BusinessObjectCollection.Add(new BusinessObject() { TaskId = 7, TaskName = "Parent Task 3", StartDate = new DateTime(2017, 10, 28), Duration = 4, Progress = 45, ParentId = null, Priority = "High" });
BusinessObjectCollection.Add(new BusinessObject() { TaskId = 8, TaskName = "Child Task 7", StartDate = new DateTime(2017, 10, 29), Duration = 3, Progress = 38, ParentId = 7, Priority = "Critical" });
BusinessObjectCollection.Add(new BusinessObject() { TaskId = 9, TaskName = "Child Task 8", StartDate = new DateTime(2017, 10, 30), Duration = 7, Progress = 70, ParentId = 7, Priority = "Low" });
return BusinessObjectCollection;
}
}
}---
Paste
Copy a group of cells with Ctrl + C, then select a target cell and press Ctrl + V to paste.
Requirements for paste to work:
- Selection
Mode="Cell"andCellSelectionMode="Box" EditMode.Batchediting enabled
<SfTreeGrid DataSource="@TreeData"
IdMapping="TaskId"
ParentIdMapping="ParentId"
TreeColumnIndex="1"
AllowPaging="true"
Toolbar="@(new List<string> { "Add", "Delete", "Update", "Cancel" })">
<TreeGridPageSettings PageSize="5" />
<TreeGridSelectionSettings
Type="Syncfusion.Blazor.Grids.SelectionType.Multiple"
Mode="Syncfusion.Blazor.Grids.SelectionMode.Cell"
CellSelectionMode="Syncfusion.Blazor.Grids.CellSelectionMode.Box" />
<TreeGridEditSettings
AllowAdding="true"
AllowEditing="true"
AllowDeleting="true"
Mode="EditMode.Batch" />
<TreeGridColumns>
<TreeGridColumn Field="TaskId" HeaderText="Task ID" Width="80" IsPrimaryKey="true" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<TreeGridColumn Field="TaskName" HeaderText="Task Name" Width="155" />
<TreeGridColumn Field="StartDate" HeaderText="Start Date" Width="100" Format="d" Type="Syncfusion.Blazor.Grids.ColumnType.Date" EditType="Syncfusion.Blazor.Grids.EditType.DatePickerEdit" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<TreeGridColumn Field="Duration" HeaderText="Duration" Width="80" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<TreeGridColumn Field="Progress" HeaderText="Progress" Width="80" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<TreeGridColumn Field="Priority" HeaderText="Priority" Width="80" />
</TreeGridColumns>
</SfTreeGrid>Paste limitations:
| Scenario | Result |
|---|---|
| String → Number column | Displays as NaN |
| String → Date column | Displays as empty cell |
---
Clipboard Events
Use TreeGridEvents to intercept clipboard operations:
| Event | Trigger | Can Cancel? |
|---|---|---|
BeforeCopyPaste | Before any copy or paste action | ✅ — cancels entire copy/paste |
BeforeCellPaste | Before pasting into each individual cell | ✅ — can cancel or change the value per cell |
@using Syncfusion.Blazor.TreeGrid
<TreeGridEvents TValue="BusinessObject"
BeforeCopyPaste="OnBeforeCopyPaste"
BeforeCellPaste="OnBeforeCellPaste">
</TreeGridEvents>
@code {
public void OnBeforeCopyPaste(Syncfusion.Blazor.TreeGrid.BeforeCopyPasteEventArgs args)
{
// args.Cancel = true; // Prevent the entire copy/paste
}
public void OnBeforeCellPaste(Syncfusion.Blazor.TreeGrid.BeforeCellPasteEventArgs<BusinessObject> args)
{
// args.Cancel = true; // Skip paste for this specific cell
// args.Value = ...; // Or override the value being pasted
}
}---
Columns in Syncfusion Blazor TreeGrid
Namespace note:TextAlign,ColumnType,EditType, andClipModebelong toSyncfusion.Blazor.Grids, notSyncfusion.Blazor.TreeGrid. Always qualify them with the full namespace (e.g.,Syncfusion.Blazor.Grids.TextAlign.Right,Syncfusion.Blazor.Grids.ColumnType.Date) to avoid CS0104 ambiguity errors.
Table of Contents
- Basic Column Definition
- Column Properties Reference
- Complex Data Binding
- Column Format
- Column Type
- Checkbox Column
- Stacked Headers
- Column Template
- Header Template
- Header Text
- Column Chooser
- Column Menu
- Column Reorder
- Column Resizing
- Column Spanning
- Auto-Fit Columns
- Freeze Columns
- Responsive Columns
- Show or Hide Columns by External Button
---
Basic Column Definition
Column definitions act as the data source schema for the TreeGrid and determine how values render. TreeGrid operations such as sorting, filtering, and searching operate based on the column definitions. The Field property of the TreeGridColumn component is required to map data source values to TreeGrid columns.
If the columnFielddoes not match a property in the data source, the column cells render empty. TheTreeColumnIndexproperty denotes the column used to expand and collapse child rows.
<SfTreeGrid DataSource="@Data" IdMapping="Id" ParentIdMapping="ParentId" TreeColumnIndex="1">
<TreeGridColumns>
<TreeGridColumn Field="Id" HeaderText="Task ID" Width="80"
IsPrimaryKey="true"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<TreeGridColumn Field="Name" HeaderText="Task Name" Width="200" />
<TreeGridColumn Field="Status" HeaderText="Status" Width="120" />
<TreeGridColumn Field="Progress" HeaderText="Progress%" Width="100"
Format="P0"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
</TreeGridColumns>
</SfTreeGrid>---
Column Properties Reference
| Property | Type | Description |
|---|---|---|
Field | string | Maps to the data source property (required) |
HeaderText | string | Column header label (defaults to Field name) |
Width | string/int | Column width (px or %) |
MinWidth | string | Minimum width (used with resizing) |
MaxWidth | string | Maximum width |
TextAlign | Syncfusion.Blazor.Grids.TextAlign | Left / Center / Right / Justify |
HeaderTextAlign | Syncfusion.Blazor.Grids.TextAlign | Header-only text alignment |
Type | Syncfusion.Blazor.Grids.ColumnType | String, Integer, Decimal, Double, Long, Boolean, Date, DateTime, DateOnly, TimeOnly, CheckBox, None |
Format | string | Value format string (e.g., "d", "C2", "P0") |
IsPrimaryKey | bool | Marks primary key column (required for editing) |
Visible | bool | Show/hide the column |
AllowSorting | bool | Enable/disable sort for this column |
AllowFiltering | bool | Enable/disable filter for this column |
AllowEditing | bool | Enable/disable editing for this column |
AllowReordering | bool | Allow drag-reorder for this column |
AllowResizing | bool | Allow resize handle for this column |
ClipMode | ClipMode | EllipsisWithTooltip / Clip / Ellipsis |
CustomAttributes | object | Add HTML attributes to column cells |
ValueAccessor | Func | Custom value transform function |
DisableHtmlEncode | bool | Render HTML content in cells (see cell.md) |
ShowCheckbox | bool | Renders checkboxes in the existing column |
AutoCheckHierarchy | bool | Enables hierarchical checkbox selection |
DisplayAsCheckBox | bool | Renders boolean values as checkboxes |
LockColumn | bool | Locks column to first position; disables reordering |
HideAtMedia | string | CSS media query to toggle column visibility responsively |
ShowInColumnChooser | bool | Include/exclude column from the column chooser dialog |
ShowColumnMenu | bool | Enable/disable column menu for this column |
AutoSpan | AutoSpanMode | Controls cell spanning behavior for this column |
IsFrozen | bool | Freezes the column in place |
Freeze | FreezeDirection | Direction to freeze the column (Left/Right) |
---
Complex Data Binding
Complex data binding can be achieved by using the dot (.) operator in the column Field. In the following example, Task.TaskName and Task.Duration are complex data fields.
<TreeGridColumn Field="Task.TaskName" HeaderText="Task Name" Width="160" />
<TreeGridColumn Field="Task.Duration" HeaderText="Duration" Width="100" />public class BusinessObject
{
public int TaskId { get; set; }
public int? ParentId { get; set; }
public TaskDetails Task { get; set; } // nested object
public int Progress { get; set; }
public string Priority { get; set; }
}
public class TaskDetails
{
public string TaskName { get; set; }
public int Duration { get; set; }
}Expando data binding
TreeGrid supports complex data binding with ExpandoObject. Task.TaskName and Task.Duration are complex data fields using ExpandoObject.
<SfTreeGrid DataSource="@TreeData" AllowPaging="true" IdMapping="TaskID" ParentIdMapping="ParentID" TreeColumnIndex="1">
<TreeGridColumns>
<TreeGridColumn Field="TaskID" HeaderText="Task ID" Width="80"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right"></TreeGridColumn>
<TreeGridColumn Field="Task.TaskName" HeaderText="Task Name" Width="160"></TreeGridColumn>
<TreeGridColumn Field="Task.Duration" HeaderText="Duration" Width="160"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right"></TreeGridColumn>
<TreeGridColumn Field="Progress" HeaderText="Progress" Width="100"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right"></TreeGridColumn>
<TreeGridColumn Field="Priority" HeaderText="Priority" Width="80"></TreeGridColumn>
</TreeGridColumns>
</SfTreeGrid>---
Column Format
To format cell values based on culture, use the Format property of the TreeGridColumn component. The TreeGrid uses the Internationalization library to format number values.
<!-- Currency -->
<TreeGridColumn Field="Price" HeaderText="Price" Format="C2"
Type="Syncfusion.Blazor.Grids.ColumnType.Integer"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<!-- Percentage -->
<TreeGridColumn Field="Progress" HeaderText="Progress" Format="P0"
Type="Syncfusion.Blazor.Grids.ColumnType.Integer"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<!-- Short date -->
<TreeGridColumn Field="StartDate" HeaderText="Start Date" Format="yMd"
Type="Syncfusion.Blazor.Grids.ColumnType.Date" />
<!-- Long date/time -->
<TreeGridColumn Field="OrderDate" HeaderText="Order Date" Format="dd/MM/yyyy HH:mm"
Type="Syncfusion.Blazor.Grids.ColumnType.DateTime" />By default, number and date values are formatted using the en-US locale.
Number formatting
| Format | Description | Remarks |
|---|---|---|
N | Denotes numeric type | Follow with a precision specifier, such as N2 or N3, to control decimal places |
C | Denotes currency type | Follow with a precision specifier, such as C2 or C3, to control decimal places |
P | Denotes percentage type | Expects input from 0 to 1. For example, 0.2 formats as 20%. Follow with a precision specifier such as P2 or P3 |
Date formatting
Use built-in date format strings to format date values. For built-in date formats, specify the Format property as a string (e.g., "d", "yMd").
<TreeGridColumn Field="OrderDate" HeaderText="Order Date" Format="yMd"
Type="Syncfusion.Blazor.Grids.ColumnType.Date" Width="160" />---
Column Type
Column type can be specified using the Type property of TreeGridColumn. It specifies the type of data the column binds. If the Format is defined for a column, the column uses Type to select the appropriate format option (number or date).
Always set Type for non-string columns so filtering and sorting work correctly.
Important: If theTypeis not defined, it will be determined from the first record of theDataSource. Syncfusion Blazor TreeGrid only supportsColumnType.Integerfor numeric columns. Do not useColumnType.Number.
<TreeGridColumn Field="TaskId" Type="Syncfusion.Blazor.Grids.ColumnType.Integer" />
<TreeGridColumn Field="StartDate" Type="Syncfusion.Blazor.Grids.ColumnType.Date" />
<TreeGridColumn Field="IsActive" Type="Syncfusion.Blazor.Grids.ColumnType.Boolean" />| Column Type | Description |
|---|---|
String | Represents text data. This is the default type when Type is not explicitly defined. |
Decimal | Displays decimal numeric values. |
Double | Displays double-precision floating-point values. |
Integer | Represents integer numeric values. |
Long | Represents long integer values. |
None | Indicates no specific data type. |
Boolean | Displays boolean values, typically rendered by default as text (true/false) or as checkboxes when DisplayAsCheckBox is enabled. |
Date | Displays date values with comprehensive formatting support. |
DateTime | Displays date and time values, offering various formatting options. |
DateOnly | Represents DateOnly values (available in .NET 7 and later). |
TimeOnly | Represents TimeOnly values (available in .NET 7 and later). |
CheckBox | Renders a checkbox within the column, primarily used for row selection. |
Example of using Integer for numeric columns:
<!-- Currency values - use Integer with Format="C0" -->
<TreeGridColumn Field="PlannedBudget" HeaderText="Budget"
Type="Syncfusion.Blazor.Grids.ColumnType.Integer" Format="C0"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<!-- Percentage values - use Integer with Format="P0" -->
<TreeGridColumn Field="Progress" HeaderText="Progress"
Type="Syncfusion.Blazor.Grids.ColumnType.Integer" Format="P0"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<!-- Plain integers -->
<TreeGridColumn Field="Duration" HeaderText="Duration (Days)"
Type="Syncfusion.Blazor.Grids.ColumnType.Integer"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />---
Checkbox Column
To render checkboxes in the existing column, set the ShowCheckbox property of the TreeGridColumn as true.
It is also possible to select the rows hierarchically using checkboxes in the Tree Grid by enabling the AutoCheckHierarchy property. When a parent record checkbox is checked, all child record checkboxes will also get checked.
<SfTreeGrid IdMapping="TaskId" ParentIdMapping="ParentId" DataSource="@TreeGridData"
TreeColumnIndex="1" AutoCheckHierarchy="true">
<TreeGridColumns>
<TreeGridColumn Field="TaskId" HeaderText="Task ID" Width="80"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right"></TreeGridColumn>
<TreeGridColumn Field="TaskName" HeaderText="Task Name" ShowCheckbox="true" Width="90"></TreeGridColumn>
<TreeGridColumn Field="StartDate" HeaderText="Start Date"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right"
Format="yMd" Type="Syncfusion.Blazor.Grids.ColumnType.Date" Width="90"></TreeGridColumn>
<TreeGridColumn Field="Duration" HeaderText="Duration"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" Width="80"></TreeGridColumn>
<TreeGridColumn Field="Progress" HeaderText="Progress"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" Width="80"></TreeGridColumn>
</TreeGridColumns>
</SfTreeGrid>---
Stacked Headers
Group related columns under a shared header row using nested TreeGridColumns:
<TreeGridColumns>
<TreeGridColumn HeaderText="Order Details" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right">
<TreeGridColumns>
<TreeGridColumn Field="OrderId" HeaderText="Order ID" Width="110"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<TreeGridColumn Field="OrderName" HeaderText="Order Name" Width="220"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Left" />
<TreeGridColumn Field="OrderDate" HeaderText="Order Date" Width="120"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right"
Format="yMd" Type="Syncfusion.Blazor.Grids.ColumnType.Date" />
</TreeGridColumns>
</TreeGridColumn>
<TreeGridColumn HeaderText="Shipment Details" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Center">
<TreeGridColumns>
<TreeGridColumn Field="ShipmentCategory" HeaderText="Shipment Category" Width="170" />
<TreeGridColumn Field="Units" HeaderText="Units" Width="220"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Left" />
<TreeGridColumn Field="ShippedDate" HeaderText="Shipment Date" Width="120"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right"
Format="yMd" Type="Syncfusion.Blazor.Grids.ColumnType.Date" />
</TreeGridColumns>
</TreeGridColumn>
</TreeGridColumns>---
Column Template
The Column template has options to display custom element value or content in the column. You can use the Template of the TreeGridColumn component to specify the custom content. Inside the Template, you can access the data using the implicit named parameter context.
The column template feature is used to render the customized element value in the UI for a particular column. Data operations like filtering, sorting, etc., will not work based on the column template values. It will be handled based on the values you have provided to the particular column in the datasource.
<SfTreeGrid DataSource="@TreeData" IdMapping="EmployeeID" ParentIdMapping="ParentId" TreeColumnIndex="0">
<TreeGridColumns>
<TreeGridColumn Field="Name" HeaderText="Name" Width="160"></TreeGridColumn>
<TreeGridColumn HeaderText="Employee Image" Width="140">
<Template>
@{
var employee = (context as Employee);
<div class="image">
<img src="@UriHelper.ToAbsoluteUri($"images/TreeGrid/{employee.Name}.png")"
alt="@employee.EmployeeID" />
</div>
}
</Template>
</TreeGridColumn>
<TreeGridColumn Field="Designation" HeaderText="Designation" Width="170"></TreeGridColumn>
<TreeGridColumn Field="EmpID" HeaderText="Employee ID" Width="120"></TreeGridColumn>
</TreeGridColumns>
</SfTreeGrid>Tree Grid actions such as editing, filtering, and sorting depend upon the columnField. If theFieldis not specified in the template column, the tree grid actions cannot be performed.
Using conditions inside template
Template elements can be rendered based on conditions inside the Template of the TreeGridColumn component.
<TreeGridColumn HeaderText="Template Column" Width="90">
<Template>
@{
var row = (context as SelfReferenceData);
@if (row.Duration > 1)
{
<SfCheckBox Checked="true"></SfCheckBox>
}
else
{
<SfCheckBox Checked="false"></SfCheckBox>
}
}
</Template>
</TreeGridColumn>Using hyperlink column
You can use the Template property of the TreeGridColumn to render hyperlinks and use NavigationManager for routing.
<TreeGridColumn HeaderText="User profile" TextAlign="TextAlign.Center" Width="120">
<Template>
@{
var Employee = (context as EmployeeData);
<div><a href="#" @onclick="@(() => Navigate(Employee))">View</a></div>
}
</Template>
</TreeGridColumn>
@code {
private void Navigate(EmployeeData Employee)
{
UriHelper.NavigateTo($"{ Employee.Link}/{Employee.EmployeeID.ToString()}/{Employee.Name}/{ Employee.Title}");
}
}---
Header Template
Customize the header element using the HeaderTemplate property:
<TreeGridColumn Field="Name" HeaderText="Name" Width="160">
<HeaderTemplate>
<div>
<span class="e-icon-userlogin e-icons employee"></span> Name
</div>
</HeaderTemplate>
</TreeGridColumn>
<TreeGridColumn Field="Priority" Width="120">
<HeaderTemplate>
<span>⚑ Priority</span>
</HeaderTemplate>
</TreeGridColumn>---
Column Chooser
The column chooser has options to show or hide columns dynamically. It can be enabled by defining the ShowColumnChooser property as true and adding "ColumnChooser" to the Toolbar.
<SfTreeGrid IdMapping="TaskId" ParentIdMapping="ParentId" DataSource="@TreeGridData"
TreeColumnIndex="1" ShowColumnChooser="true" Toolbar="@ToolbarItems">
<TreeGridColumns>
<TreeGridColumn Field="TaskId" HeaderText="Task ID" Width="80"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right"></TreeGridColumn>
<TreeGridColumn Field="TaskName" HeaderText="Task Name" Width="90"
ShowInColumnChooser="false"></TreeGridColumn>
<TreeGridColumn Field="StartDate" HeaderText="Start Date"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right"
Format="yMd" Type="Syncfusion.Blazor.Grids.ColumnType.Date" Width="90"></TreeGridColumn>
<TreeGridColumn Field="Duration" HeaderText="Duration"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" Width="80"></TreeGridColumn>
<TreeGridColumn Field="Progress" HeaderText="Progress"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" Width="80"></TreeGridColumn>
</TreeGridColumns>
</SfTreeGrid>
@code {
public string[] ToolbarItems = new string[] { "ColumnChooser" };
}Column names can be hidden in the column chooser by defining the ShowInColumnChooser property as false.Open column chooser by external button
The column chooser can be opened programmatically using the OpenColumnChooserAsync method:
public async Task Show()
{
await this.TreeGrid.OpenColumnChooserAsync(200, 50);
}Text wrapping in column chooser
Allow long column names to wrap across multiple lines in the column chooser dialog by setting AllowTextWrap to true on TreeGridColumnChooserSettings:
<SfTreeGrid ShowColumnChooser="true" Toolbar="@ToolbarItems">
<TreeGridColumnChooserSettings AllowTextWrap="true"></TreeGridColumnChooserSettings>
<TreeGridColumns>
...
</TreeGridColumns>
</SfTreeGrid>Template support in column chooser
Customize the column chooser using Template and FooterTemplate of the TreeGridColumnChooserSettings component. Use TreeGridColumnChooserItem inside the Template and access ColumnChooserTemplateContext for column details.
<SfTreeGrid ShowColumnChooser="true" Toolbar="@(new List<string>() { "ColumnChooser" })">
<TreeGridColumnChooserSettings>
<Template>
@{
var cxt = context as ColumnChooserTemplateContext;
@foreach (var column in cxt.Columns)
{
<TreeGridColumnChooserItem Column="column"></TreeGridColumnChooserItem>
}
}
</Template>
<FooterTemplate>
@{
var cxt = context as ColumnChooserFooterTemplateContext;
var visibles = cxt.Columns.Where(x => x.Visible).Select(x => x.HeaderText).ToArray();
var hiddens = cxt.Columns.Where(x => !x.Visible).Select(x => x.HeaderText).ToArray();
}
<SfButton IsPrimary="true" OnClick="@(async () => {
await TreeGrid.ShowColumnsAsync(visibles);
await TreeGrid.HideColumnsAsync(hiddens); })">Ok</SfButton>
<SfButton @onclick="@(async () => await cxt.CancelAsync())">Cancel</SfButton>
</FooterTemplate>
</TreeGridColumnChooserSettings>
...
</SfTreeGrid>Column chooser with group template
Group columns inside the column chooser by wrapping TreeGridColumnChooserItem inside TreeGridColumnChooserItemGroup.
Programmatic column access
⚠️ CRITICAL: When accessing columns programmatically, use GetColumnsAsync() (async method), NOT GetColumns(). The synchronous method does not exist in Syncfusion Blazor TreeGrid.
// ✅ CORRECT - Use async/await
private async Task ToggleColumnVisibility(string fieldName)
{
var columns = await TreeGridRef.GetColumnsAsync(); // ✅ MUST await GetColumnsAsync()
var column = columns.FirstOrDefault(col => col.Field == fieldName);
if (column != null)
{
column.Visible = !column.Visible;
await TreeGridRef.RefreshAsync();
}
}
// ❌ WRONG - Do NOT use GetColumns()
// var columns = TreeGridRef.GetColumns(); // ERROR: This method does not existOther async methods for columns:
await TreeGridRef.GetColumnsAsync(); // Get all columns
await TreeGridRef.ShowColumnsAsync(new string[] { "Task ID", "Duration" }); // Show columns by HeaderText
await TreeGridRef.HideColumnsAsync(new string[] { "Task ID", "Duration" }); // Hide columns by HeaderText
await TreeGridRef.ReorderColumnsAsync(new List<string> { "Field1" }, "Field2"); // Reorder columns
await TreeGridRef.AutoFitColumnsAsync(new string[] { }); // Auto-fit all columns
await TreeGridRef.AutoFitColumnsAsync(new string[] { "TaskName" }); // Auto-fit specific columns---
Column Menu
The column menu has options to integrate features like sorting, filtering, and autofit. It shows a menu with the integrated feature when users click on an icon in the column header. To enable column menu, set the ShowColumnMenu property as true.
<SfTreeGrid IdMapping="TaskId" ParentIdMapping="ParentId" DataSource="@TreeGridData"
TreeColumnIndex="1" ShowColumnMenu="true" AllowFiltering="true"
AllowSorting="true" AllowResizing="true">
<TreeGridFilterSettings Type="Syncfusion.Blazor.TreeGrid.FilterType.Menu" />
<TreeGridColumns>
<TreeGridColumn Field="TaskId" HeaderText="Task ID" Width="80"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right"></TreeGridColumn>
<TreeGridColumn Field="TaskName" HeaderText="Task Name" MinWidth="170" MaxWidth="250" Width="180"></TreeGridColumn>
<TreeGridColumn Field="Duration" HeaderText="Duration" MinWidth="50" MaxWidth="150"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" Width="80"></TreeGridColumn>
<TreeGridColumn Field="Progress" HeaderText="Progress"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" Width="80"></TreeGridColumn>
</TreeGridColumns>
</SfTreeGrid>Default Column Menu Items (automatically enabled):
| Item | Description |
|---|---|
SortAscending | Sort the current column in ascending order |
SortDescending | Sort the current column in descending order |
AutoFit | Auto fit the current column |
AutoFitAll | Auto fit all columns |
Filter | Show the filter option as given in FilterSettings.Type |
Disable column menu for specific columns:
<TreeGridColumn Field="Id" ShowColumnMenu="false" />The column menu can be disabled for a particular column by defining theShowColumnMenuproperty of theTreeGridColumnas false.
Column Menu Event Handling
⚠️ CRITICAL: Use the correct event args type ColumnMenuClickEventArgs, NOT ColumnMenuItemClickEventArgs.
// ✅ CORRECT - Use ColumnMenuClickEventArgs
private async Task OnColumnMenuItemClicked(ColumnMenuClickEventArgs args)
{
var columnName = args.Column?.HeaderText;
var menuItemId = args.Item?.Id;
var menuItemText = args.Item?.Text;
// Handle menu item click
if(args.Item?.Id == "SortAscending")
{
// Sorting ascending logic
}
else if(args.Item?.Id == "SortDescending")
{
// Sorting descending logic
}
}
// ❌ WRONG - Do NOT use ColumnMenuItemClickEventArgs
// private async Task OnColumnMenuItemClicked(ColumnMenuItemClickEventArgs args) // ERROR: Type doesn't existAvailable properties in ColumnMenuClickEventArgs:
Column– The column on which menu is clickedItem– The menu item that was clickedElement– The menu element reference
---
Column Reorder
Reordering can be done by drag and drop of a particular column header from one index to another index within the tree grid. To enable reordering, set the AllowReordering property to true.
<SfTreeGrid IdMapping="TaskId" ParentIdMapping="ParentId" AllowReordering="true"
DataSource="@TreeGridData" TreeColumnIndex="1">
<TreeGridColumns>
<TreeGridColumn Field="TaskId" HeaderText="Task ID" Width="80"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right"></TreeGridColumn>
<TreeGridColumn Field="TaskName" HeaderText="Task Name" MinWidth="170" MaxWidth="250" Width="180"></TreeGridColumn>
<TreeGridColumn Field="Duration" HeaderText="Duration" MinWidth="50" MaxWidth="150"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" Width="80"></TreeGridColumn>
<TreeGridColumn Field="Progress" HeaderText="Progress"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" Width="80"></TreeGridColumn>
</TreeGridColumns>
</SfTreeGrid>You can disable reordering a particular column by setting theAllowReorderingproperty of theTreeGridColumnto false.
Reorder single column
private async Task ReorderColumn()
{
await TreeGrid.ReorderColumnsAsync(new List<string>() { "TaskName" }, "Duration");
}Reorder multiple columns
private async Task ReorderMultipleColumns()
{
await TreeGrid.ReorderColumnsAsync(new List<string>() { "TaskName", "Duration" }, "Progress");
}Programmatic Column Reordering
⚠️ CRITICAL: Use ReorderColumnsAsync() with a List<string> of fields, NOT ReorderColumnAsync() with two strings.
// ✅ CORRECT - Use ReorderColumnsAsync with List<string>
await TreeGridRef.ReorderColumnsAsync(new List<string> { "TaskName" }, "Progress");
await TreeGridRef.ReorderColumnsAsync(new List<string> { "Name", "Email" }, "Salary");
// ❌ WRONG - Do NOT use ReorderColumnAsync or pass plain strings
// await TreeGridRef.ReorderColumnAsync("TaskName", "Progress"); // ERROR: Wrong APIAvailable event args:
- ColumnReorderingEventArgs – Fired before reorder (can cancel via
Cancelproperty) Column– Column being reorderedColumnIndex– Target indexCancel– Set to true to prevent reordering- ColumnReorderedEventArgs – Fired after reorder completes
Column– Column that was reorderedColumnIndex– New column index
---
Column Resizing
Column width can be resized by clicking and dragging the right edge of the column header. Each column can be auto resized by double-clicking the right edge of the column header to fit the width of that column based on the widest cell content. To enable column resize, set the AllowResizing property to true.
<SfTreeGrid AllowResizing="true">
...
</SfTreeGrid>You can disable resizing for a particular column by setting theAllowResizingproperty of theTreeGridColumncomponent to false. In RTL mode, you can click and drag the left edge of the header cell to resize the column.
Min and max width
Column resize can be restricted between minimum and maximum width by defining the MinWidth and MaxWidth properties in TreeGridColumn:
<TreeGridColumn Field="TaskName" HeaderText="Task Name" MinWidth="170" MaxWidth="250" Width="180" />
<TreeGridColumn Field="Duration" HeaderText="Duration" MinWidth="50" MaxWidth="150" Width="80" />Touch interaction
When the right edge of the header cell is tapped, a floating handler will be visible over the right border of the column. To resize the column, tap and drag the floating handler as needed. You can AutoFit a column by using the Column menu of the tree grid.
Programmatically auto-fit a column:
await TreeRef.AutoFitColumnsAsync(new string[] { "TaskName" });Prevent resizing on a specific column:
<TreeGridColumn Field="Id" AllowResizing="false" />---
Column Spanning
Column spanning in the Blazor TreeGrid provides automatic vertical merging of adjacent cells within the same column when identical values are detected. This improves readability by consolidating repeated values into a single taller cell, which is especially useful when the same value appears across consecutive rows.
Automatic Column Spanning
Enable column spanning by setting the AutoSpan property of the SfTreeGrid component to AutoSpanMode.Column:
<SfTreeGrid @ref="TreeGridInstance" DataSource="@TreeData" IdMapping="Id"
ParentIdMapping="ParentId" AutoSpan="AutoSpanMode.Column"
TreeColumnIndex="1" GridLines="GridLine.Both">
<TreeGridColumns>
<TreeGridColumn Field="Id" HeaderText="ID" Width="80"
TextAlign="TextAlign.Center" IsPrimaryKey></TreeGridColumn>
<TreeGridColumn Field="Name" HeaderText="Developer" Width="150"></TreeGridColumn>
<TreeGridColumn Field="Slot1" HeaderText="10:00 - 11:00 AM" Width="150"></TreeGridColumn>
<TreeGridColumn Field="Slot2" HeaderText="11:00 - 12:00 AM" Width="150"></TreeGridColumn>
<TreeGridColumn Field="Status" HeaderText="Status" Width="150"></TreeGridColumn>
</TreeGridColumns>
</SfTreeGrid>AutoSpan Modes
The AutoSpanMode enumeration provides multiple options for cell merging behavior:
| Mode | Description |
|---|---|
AutoSpanMode.None | Disables automatic cell spanning (default). |
AutoSpanMode.Row | Enables horizontal merging across columns within the same row. |
AutoSpanMode.Column | Enables vertical merging of adjacent cells with identical values in the same column. |
AutoSpanMode.HorizontalAndVertical | Enables both horizontal and vertical merging. Executes row merging first, followed by column merging. |
Disable column spanning for specific columns
Disable spanning on individual columns by setting their AutoSpan property to AutoSpanMode.None:
<TreeGridColumn Field="TotalBudget" HeaderText="Planned Budget" Width="140"
TextAlign="TextAlign.Right" Format="C0" AutoSpan="AutoSpanMode.None" />
<TreeGridColumn Field="PaidToDate" HeaderText="Actual Spend" Width="140"
TextAlign="TextAlign.Right" Format="C0" AutoSpan="AutoSpanMode.None" />Controlling spanning at TreeGrid and column levels
The spanning behavior is determined by how the TreeGrid-level and column-level AutoSpan settings interact. Column-level AutoSpan can only narrow the spanning directions permitted by the TreeGrid.
| TreeGrid AutoSpan | Column AutoSpan | Effective Behavior |
|---|---|---|
None | Any | No spanning. TreeGrid disables it globally. |
Row | None | No spanning. Column explicitly disables it. |
Row | Row | Row spanning only. |
Row | Column | No spanning. TreeGrid only allows row spanning. |
Row | HorizontalAndVertical | Row spanning only. TreeGrid only allows row spanning. |
Column | None | No spanning. Column explicitly disables it. |
Column | Row | No spanning. TreeGrid only allows column spanning. |
Column | Column | Column spanning only. |
Column | HorizontalAndVertical | Column spanning only. TreeGrid only allows column spanning. |
HorizontalAndVertical | None | No spanning. Column explicitly disables both directions. |
HorizontalAndVertical | Row | Row spanning only. Column narrows to Row. |
HorizontalAndVertical | Column | Column spanning only. Column narrows to Column. |
HorizontalAndVertical | HorizontalAndVertical | Row and Column spanning. |
Programmatic cell merging
Manually merge cells using the MergeCellsAsync method. Use MergeCellInfo to define the rectangular region:
| Property | Type | Description |
|---|---|---|
RowIndex | int | Zero-based index of the anchor row (top-left cell). |
ColumnIndex | int | Zero-based index of the anchor column (top-left cell). |
RowSpan | int (optional) | Number of rows to span. Defaults to 1. |
ColumnSpan | int (optional) | Number of columns to span. Defaults to 1. |
// Single merge
await TreeRef.MergeCellsAsync(new MergeCellInfo
{
RowIndex = 1,
ColumnIndex = 1,
ColumnSpan = 2
});
// Batch merge
await TreeRef.MergeCellsAsync(new[]
{
new MergeCellInfo { RowIndex = 0, ColumnIndex = 0, ColumnSpan = 2 },
new MergeCellInfo { RowIndex = 5, ColumnIndex = 0, ColumnSpan = 3 },
new MergeCellInfo { RowIndex = 7, ColumnIndex = 0, ColumnSpan = 2 }
});Clearing spanning programmatically
Use UnmergeCellsAsync to remove specific merged regions, or UnmergeAllAsync to reset all merges:
| Method | Parameter | Description |
|---|---|---|
UnmergeCellsAsync | UnmergeCellInfo | Removes a single merged area identified by its anchor cell. |
UnmergeCellsAsync | IEnumerable<UnmergeCellInfo> | Removes multiple merged areas in one batch operation. |
UnmergeAllAsync | – | Removes all merged regions in the current view. |
// Remove a specific merged region
await TreeRef.UnmergeCellsAsync(new UnmergeCellInfo { RowIndex = 1, ColumnIndex = 1 });
// Remove multiple merged regions
await TreeRef.UnmergeCellsAsync(new[]
{
new UnmergeCellInfo { RowIndex = 0, ColumnIndex = 0 },
new UnmergeCellInfo { RowIndex = 5, ColumnIndex = 0 }
});
// Remove all merged regions
await TreeRef.UnmergeAllAsync();Limitations
Column spanning is not compatible with:
- Virtualization
- Infinite Scrolling
- Row Drag and Drop
- Column Virtualization
- Detail Template
- Editing
- Export
---
Auto-Fit Columns
The AutoFitColumnsAsync method resizes the column to fit the widest cell's content without wrapping. A specific column can be autofitted at initial rendering by invoking AutoFitColumnsAsync in the DataBound event.
<SfTreeGrid @ref="TreeGrid" DataSource="@TreeGridData" IdMapping="TaskId"
ParentIdMapping="ParentId" TreeColumnIndex="1">
<TreeGridEvents DataBound="OnDataBound" TValue="TreeData.BusinessObject"></TreeGridEvents>
<TreeGridColumns>
<TreeGridColumn Field="TaskId" HeaderText="Task ID" Width="80"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right"></TreeGridColumn>
<TreeGridColumn Field="TaskName" HeaderText="Task Name" Width="160"></TreeGridColumn>
<TreeGridColumn Field="Duration" HeaderText="Duration" Width="100"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right"></TreeGridColumn>
<TreeGridColumn Field="Progress" HeaderText="Progress" Width="100"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right"></TreeGridColumn>
<TreeGridColumn Field="Priority" HeaderText="Priority" Width="80"></TreeGridColumn>
</TreeGridColumns>
</SfTreeGrid>
@code {
SfTreeGrid<TreeData.BusinessObject> TreeGrid;
private async Task OnDataBound(object e)
{
await this.TreeGrid.AutoFitColumnsAsync(new string[] { "TaskName" }); // specific column
// await this.TreeGrid.AutoFitColumnsAsync(new string[] { }); // all columns
}
}All columns can be autofitted by invoking the AutoFitColumnsAsync method without specific column names (pass an empty array).⚠️ CRITICAL Constraints
- Always Pass Parameter:
AutoFitColumnsAsync()requires a parameter (unlike other methods) - Empty Array = All Columns: Use
new string[] { }to fit all columns - Specific Columns: Pass field names in the array to fit only those columns
- Component Lifecycle: Best called in
DataBoundevent orOnAfterRenderAsync(bool firstRender)wherefirstRender == true
---
Lock Columns
Columns can be locked by using the LockColumn property. The locked columns will be moved to the first position and cannot be reordered.
<SfTreeGrid IdMapping="TaskId" ParentIdMapping="ParentId" DataSource="@TreeGridData"
TreeColumnIndex="1" AllowReordering="true">
<TreeGridColumns>
<TreeGridColumn Field="TaskId" HeaderText="Task ID" Width="80"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right"></TreeGridColumn>
<TreeGridColumn Field="TaskName" HeaderText="Task Name" Width="90"></TreeGridColumn>
<TreeGridColumn Field="StartDate" HeaderText="Start Date"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right"
Format="yMd" Type="Syncfusion.Blazor.Grids.ColumnType.Date" Width="90"></TreeGridColumn>
<TreeGridColumn Field="Duration" LockColumn="true" HeaderText="Duration"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" Width="80"></TreeGridColumn>
<TreeGridColumn Field="Progress" HeaderText="Progress"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" Width="80"></TreeGridColumn>
</TreeGridColumns>
</SfTreeGrid>---
Freeze Columns
Fix columns to the left (or right) so they stay visible during horizontal scroll:
<SfTreeGrid FrozenColumns="2" ...>
<!-- First 2 columns will be frozen/fixed -->
<TreeGridColumns>
<TreeGridColumn Field="Id" Width="80" /> <!-- frozen -->
<TreeGridColumn Field="TaskName" Width="200" /> <!-- frozen -->
<TreeGridColumn Field="Duration" Width="100" />
<TreeGridColumn Field="Progress" Width="100" />
</TreeGridColumns>
</SfTreeGrid>Or freeze specific columns individually:
<TreeGridColumn Field="Id" IsFrozen="true" Freeze="FreezeDirection.Left" />---
Responsive Columns
The column visibility can be toggled based on media queries defined in the HideAtMedia property. The HideAtMedia accepts valid CSS Media Queries.
<SfTreeGrid IdMapping="TaskId" ParentIdMapping="ParentId" DataSource="@TreeGridData" TreeColumnIndex="1">
<TreeGridColumns>
<TreeGridColumn Field="TaskId" HeaderText="Task ID" Width="80"
HideAtMedia="max-width: 700px"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right"></TreeGridColumn>
<TreeGridColumn Field="TaskName" HeaderText="Task Name" Width="90"></TreeGridColumn>
<TreeGridColumn Field="StartDate" HeaderText="Start Date"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right"
Format="yMd" Type="Syncfusion.Blazor.Grids.ColumnType.Date" Width="90"></TreeGridColumn>
<TreeGridColumn Field="Duration" HeaderText="Duration"
HideAtMedia="max-width: 500px"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" Width="80"></TreeGridColumn>
</TreeGridColumns>
</SfTreeGrid>---
Show or Hide Columns by External Button
The tree grid columns can be shown or hidden dynamically using the external buttons by invoking the ShowColumnsAsync or HideColumnsAsync method.
<button @onclick="HideColumns">Hide Column</button>
<button @onclick="ShowColumns">Show Column</button>
<SfTreeGrid @ref="TreeGrid" IdMapping="TaskId" ParentIdMapping="ParentId"
DataSource="@TreeGridData" TreeColumnIndex="1">
<TreeGridColumns>
<TreeGridColumn Field="TaskId" HeaderText="Task ID" Width="80"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right"></TreeGridColumn>
<TreeGridColumn Field="TaskName" HeaderText="Task Name" Width="90"></TreeGridColumn>
<TreeGridColumn Field="StartDate" HeaderText="Start Date"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right"
Format="yMd" Type="Syncfusion.Blazor.Grids.ColumnType.Date" Width="90"></TreeGridColumn>
<TreeGridColumn Field="Duration" HeaderText="Duration"
TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" Width="80"></TreeGridColumn>
</TreeGridColumns>
</SfTreeGrid>
@code {
SfTreeGrid<TreeData.BusinessObject> TreeGrid;
public string[] ColumnItems = new string[] { "Task ID", "Duration" };
private async Task HideColumns()
{
await this.TreeGrid.HideColumnsAsync(ColumnItems); // hide by HeaderText
}
private async Task ShowColumns()
{
await this.TreeGrid.ShowColumnsAsync(ColumnItems); // show by HeaderText
}
}---
Context Menu in Syncfusion Blazor TreeGrid
Required namespace: Include@using Syncfusion.Blazor.Grids;forContextMenuItemModeland context menu event arguments.
⚠️ IMPORTANT - EditMode Namespace Clarification:
When usingTreeGridEditSettings.Modeproperty, always useSyncfusion.Blazor.TreeGrid.EditMode(notSyncfusion.Blazor.Grids.EditMode).
Both namespaces define an EditMode enum, but TreeGrid requires its own:```razor
<TreeGridEditSettings Mode="Syncfusion.Blazor.TreeGrid.EditMode.Row" />
```
The TreeGrid supports a right-click context menu with default grid actions and custom menu items.
Table of Contents
- Enable Context Menu
- Default Context Menu Items
- Custom Context Menu Items
- Context Menu with Paging
- Conditionally Show/Hide Items
- Key Notes
---
Enable Context Menu
Pass item names to ContextMenuItems:
<SfTreeGrid DataSource="@TreeData"
IdMapping="TaskId"
ParentIdMapping="ParentId"
ContextMenuItems="@ContextItems">
<TreeGridEditSettings AllowAdding="true" AllowEditing="true" AllowDeleting="true" />
...
</SfTreeGrid>
@code {
private List<object> ContextItems = new()
{
"AutoFit", "AutoFitAll",
"SortAscending", "SortDescending",
"Edit", "Delete", "Save", "Cancel",
"PdfExport", "ExcelExport", "CsvExport",
"FirstPage", "PrevPage", "LastPage", "NextPage"
};
}---
Default Context Menu Items
| Item | Action |
|---|---|
AutoFit | Auto-fit the clicked column |
AutoFitAll | Auto-fit all columns |
SortAscending | Sort column ascending |
SortDescending | Sort column descending |
Edit | Edit the clicked row |
Delete | Delete the clicked row |
Save | Save pending edit |
Cancel | Cancel pending edit |
Copy | Copy selected cells |
PdfExport | Export to PDF |
ExcelExport | Export to Excel |
CsvExport | Export to CSV |
FirstPage | Navigate to first page |
PrevPage | Navigate to previous page |
LastPage | Navigate to last page |
NextPage | Navigate to next page |
AddRecord | Add a new row |
Indent | Indent selected row (make it a child) |
Outdent | Outdent selected row (make it a sibling) |
CollapseAll | Collapse all rows |
ExpandAll | Expand all rows |
---
Custom Context Menu Items
Add custom items using ContextMenuItemModel:
<SfTreeGrid ContextMenuItems="@ContextItems">
<TreeGridEvents TValue="TaskItem" ContextMenuItemClicked="OnContextMenuClick" />
...
</SfTreeGrid>
@code {
private List<object> ContextItems = new()
{
"Edit", "Delete",
new Syncfusion.Blazor.Grids.ContextMenuItemModel
{
Text = "View Details",
Id = "view_details",
IconCss = "e-icons e-eye"
},
new Syncfusion.Blazor.Grids.ContextMenuItemModel
{
Text = "Duplicate Row",
Id = "duplicate_row",
IconCss = "e-icons e-copy"
}
};
private void OnContextMenuClick(Syncfusion.Blazor.Grids.ContextMenuClickEventArgs<TaskItem> args)
{
switch (args.Item.Id)
{
case "view_details":
Console.WriteLine($"Viewing: {args.RowInfo.RowData.TaskName}");
// navigate or open a dialog
break;
case "duplicate_row":
var copy = args.RowInfo.RowData;
// add a copy to data source
break;
}
}
}---
Context Menu with Paging
When enabling paging-related context menu items (FirstPage, PrevPage, NextPage, LastPage), ensure your data source has enough records to produce multiple pages:
@using Syncfusion.Blazor.TreeGrid;
<SfTreeGrid DataSource="@TreeData"
IdMapping="TaskId"
ParentIdMapping="ParentId"
AllowPaging="true"
AllowSorting="true"
TreeColumnIndex="1"
ContextMenuItems="@(new List<object>() { "SortAscending", "SortDescending", "FirstPage", "PrevPage", "NextPage", "LastPage", "Edit", "Delete", "AutoFit" })">
<TreeGridEditSettings AllowAdding="true" AllowEditing="true" AllowDeleting="true" Mode="EditMode.Row"></TreeGridEditSettings>
<TreeGridPageSettings PageSize="2"></TreeGridPageSettings>
<TreeGridColumns>
<TreeGridColumn Field="TaskId" HeaderText="Task ID" IsPrimaryKey="true" Width="80"></TreeGridColumn>
<TreeGridColumn Field="TaskName" HeaderText="Task Name" Width="200"></TreeGridColumn>
<TreeGridColumn Field="Duration" HeaderText="Duration" Width="120"></TreeGridColumn>
<TreeGridColumn Field="Priority" HeaderText="Priority" Width="100"></TreeGridColumn>
<TreeGridColumn Field="Progress" HeaderText="Progress" Width="100"></TreeGridColumn>
</TreeGridColumns>
</SfTreeGrid>
@code {
public class BusinessObject
{
public int TaskId { get; set; }
public string TaskName { get; set; }
public int Duration { get; set; }
public string Priority { get; set; }
public int Progress { get; set; }
public int? ParentId { get; set; }
}
public List<BusinessObject> TreeData = new List<BusinessObject>();
protected override void OnInitialized()
{
// Generate 30 records to demonstrate paging with PageSize="2" (creates 15 pages)
int taskId = 1;
// Parent Task 1 with children
TreeData.Add(new BusinessObject() { TaskId = taskId, TaskName = "Parent Task 1", Duration = 50000, Progress = 70, ParentId = null, Priority = "High" });
int parentId = taskId++;
for (int i = 0; i < 4; i++)
TreeData.Add(new BusinessObject() { TaskId = taskId++, TaskName = $"Child Task {i + 1}", Duration = 40000 + (i * 5000), Progress = 65 + i * 3, ParentId = parentId, Priority = new[] { "High", "Normal", "Low", "Critical" }[i] });
// Parent Task 2 with children
TreeData.Add(new BusinessObject() { TaskId = taskId, TaskName = "Parent Task 2", Duration = 60000, Progress = 75, ParentId = null, Priority = "Normal" });
parentId = taskId++;
for (int i = 0; i < 4; i++)
TreeData.Add(new BusinessObject() { TaskId = taskId++, TaskName = $"Child Task {i + 5}", Duration = 50000 + (i * 5000), Progress = 55 + i * 4, ParentId = parentId, Priority = new[] { "Critical", "High", "Normal", "Low" }[i] });
// Parent Task 3 with children
TreeData.Add(new BusinessObject() { TaskId = taskId, TaskName = "Parent Task 3", Duration = 70000, Progress = 80, ParentId = null, Priority = "Critical" });
parentId = taskId++;
for (int i = 0; i < 4; i++)
TreeData.Add(new BusinessObject() { TaskId = taskId++, TaskName = $"Child Task {i + 9}", Duration = 45000 + (i * 3000), Progress = 70 + i * 2, ParentId = parentId, Priority = new[] { "Low", "Normal", "High", "Critical" }[i] });
// Parent Task 4 with children
TreeData.Add(new BusinessObject() { TaskId = taskId, TaskName = "Parent Task 4", Duration = 55000, Progress = 65, ParentId = null, Priority = "Low" });
parentId = taskId++;
for (int i = 0; i < 4; i++)
TreeData.Add(new BusinessObject() { TaskId = taskId++, TaskName = $"Child Task {i + 13}", Duration = 48000 + (i * 4000), Progress = 60 + i * 3, ParentId = parentId, Priority = new[] { "Normal", "Critical", "Low", "High" }[i] });
// Parent Task 5 with children
TreeData.Add(new BusinessObject() { TaskId = taskId, TaskName = "Parent Task 5", Duration = 65000, Progress = 85, ParentId = null, Priority = "High" });
parentId = taskId++;
for (int i = 0; i < 4; i++)
TreeData.Add(new BusinessObject() { TaskId = taskId++, TaskName = $"Child Task {i + 17}", Duration = 52000 + (i * 6000), Progress = 75 + i * 2, ParentId = parentId, Priority = new[] { "High", "Low", "Normal", "Critical" }[i] });
}
}Key Points:
PageSize="2"displays 2 records per page with 30 total records (15 pages)- Paging context menu items are now functional for navigating between multiple pages
- Right-click any row to access FirstPage, PrevPage, NextPage, and LastPage options
---
Conditionally Show/Hide Items
Use ContextMenuOpen to hide items based on row data:
<TreeGridEvents TValue="TaskItem"
ContextMenuOpen="OnContextMenuOpen"
ContextMenuItemClicked="OnMenuClick" />
@code {
private void OnContextMenuOpen(ContextMenuOpenEventArgs<TaskItem> args)
{
// Hide Delete for locked rows
foreach (var item in args.Items)
{
if (item.Id == "TreeGrid_delete" && args.RowInfo.RowData?.IsLocked == true)
item.Hidden = true;
}
}
}Expand/Collapse Best Practice
Use the TreeGrid key-based expand/collapse API for row actions:
await TreeGridRef.ExpandByKeyAsync(rowData.TaskId);
await TreeGridRef.CollapseByKeyAsync(rowData.TaskId);---
Key Notes
- The context menu only appears when right-clicking on a data row or header cell, depending on the item type.
- Export items (
PdfExport,ExcelExport) requireAllowPdfExport="true"/AllowExcelExport="true"on the TreeGrid. Indent/Outdentitems are specific to TreeGrid (not available in regular DataGrid).
Getting Started with Syncfusion Blazor TreeGrid
Table of Contents
- Prerequisites
- Installation
- Register Service & Namespaces
- Add Stylesheet & Script
- Minimal TreeGrid Example
- Key Concepts
- Server App Setup
- MAUI Blazor Setup
---
Prerequisites
- .NET 6 / 7 / 8 / 9 SDK
- Visual Studio 2022 (v17.3+) or Visual Studio Code with C# extension
- Valid Syncfusion license (Community / Trial / Commercial)
---
Installation
Install both NuGet packages — the component and a theme:
Package Manager Console:
Install-Package Syncfusion.Blazor.TreeGrid
Install-Package Syncfusion.Blazor.Themes.NET CLI:
dotnet add package Syncfusion.Blazor.TreeGrid
dotnet add package Syncfusion.Blazor.Themes
dotnet restore---
Register Service & Namespaces
`_Imports.razor` — add namespace imports:
@using Syncfusion.Blazor
@using Syncfusion.Blazor.TreeGrid
@using Syncfusion.Blazor.Grids @* Required for events, settings, and data types *@`Program.cs` — register the Syncfusion Blazor service:
using Syncfusion.Blazor;
// Blazor WASM
builder.Services.AddSyncfusionBlazor();
await builder.Build().RunAsync();
// Blazor Server
builder.Services.AddSyncfusionBlazor();---
Add Stylesheet & Script
Blazor WASM — `wwwroot/index.html`:
<head>
<!-- Syncfusion theme (choose one) -->
<link href="_content/Syncfusion.Blazor.Themes/bootstrap5.css" rel="stylesheet" />
<!-- Core script (required) -->
<script src="_content/Syncfusion.Blazor.Core/scripts/syncfusion-blazor.min.js" type="text/javascript"></script>
</head>Blazor Server — `Pages/_Host.cshtml` or `App.razor`:
<link href="_content/Syncfusion.Blazor.Themes/bootstrap5.css" rel="stylesheet" />
<script src="_content/Syncfusion.Blazor.Core/scripts/syncfusion-blazor.min.js"></script>Available themes: bootstrap5, bootstrap5-dark, material, material-dark, material3, material3-dark, fluent, fluent-dark, tailwind, fabric, highcontrast
---
Minimal TreeGrid Example
@using Syncfusion.Blazor.TreeGrid
<SfTreeGrid DataSource="@TreeData"
IdMapping="TaskId"
ParentIdMapping="ParentId"
TreeColumnIndex="1">
<TreeGridColumns>
<TreeGridColumn Field="TaskId" HeaderText="ID" Width="80" IsPrimaryKey="true" />
<TreeGridColumn Field="TaskName" HeaderText="Task Name" Width="200" />
<TreeGridColumn Field="Duration" HeaderText="Duration" Width="100" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
<TreeGridColumn Field="Progress" HeaderText="Progress" Width="100" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right" />
</TreeGridColumns>
</SfTreeGrid>
@code {
public class TaskItem
{
public int TaskId { get; set; }
public int? ParentId { get; set; }
public string TaskName { get; set; }
public int Duration { get; set; }
public int Progress { get; set; }
}
private List<TaskItem> TreeData = new()
{
new() { TaskId = 1, ParentId = null, TaskName = "Planning", Duration = 10, Progress = 70 },
new() { TaskId = 2, ParentId = 1, TaskName = "Research", Duration = 4, Progress = 80 },
new() { TaskId = 3, ParentId = 1, TaskName = "Design", Duration = 5, Progress = 65 },
new() { TaskId = 4, ParentId = null, TaskName = "Development", Duration = 20, Progress = 40 },
new() { TaskId = 5, ParentId = 4, TaskName = "Backend", Duration = 10, Progress = 50 },
new() { TaskId = 6, ParentId = 4, TaskName = "Frontend", Duration = 10, Progress = 30 },
};
}---
Key Concepts
| Property | Purpose | Notes |
|---|---|---|
IdMapping | Unique identifier property name | Required for self-referential data |
ParentIdMapping | Parent ID property name | Null/0 = root-level row |
TreeColumnIndex | Column that shows expand/collapse icon | 0-based index |
IsPrimaryKey | Marks the primary key column | Required for editing |
TValue | Generic type parameter | Inferred from DataSource type |
Root rows are records where ParentId is null or 0.
Expand/collapse all programmatically:
<SfTreeGrid @ref="TreeRef" ...>...</SfTreeGrid>
<button @onclick="ExpandAll">Expand All</button>
<button @onclick="CollapseAll">Collapse All</button>
@code {
private SfTreeGrid<TaskItem> TreeRef;
private async Task ExpandAll() => await TreeRef.ExpandAllAsync();
private async Task CollapseAll() => await TreeRef.CollapseAllAsync();
}---
Server App Setup
Blazor Server uses Pages/_Host.cshtml for scripts and requires AddSyncfusionBlazor() in Program.cs. The rest is identical to WASM.
// Program.cs (Blazor Server)
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddSyncfusionBlazor();Gotcha: In Server apps, add @rendermode InteractiveServer (for .NET 8+ with static SSR) to the component or route.
---
MAUI Blazor Setup
// MauiProgram.cs
builder.Services.AddMauiBlazorWebView();
builder.Services.AddSyncfusionBlazor();In wwwroot/index.html:
<link href="_content/Syncfusion.Blazor.Themes/bootstrap5.css" rel="stylesheet" />
<script src="_content/Syncfusion.Blazor.Core/scripts/syncfusion-blazor.min.js"></script>---