How to Reorder, Lock or Resize the Hierarchy Expand/Collapse Column in Telerik Blazor Grid
Environment
Product | Grid for Blazor |
Description
This KB article answers the following questions:
- Can I change the position of the hierarchy expand/collapse column?
- Is it possible to lock/freeze the expand column for a hierarchical grid?
- Can I add a title to the hierarchy expand/collapse column?
- How can I change the width of the expand column in a hierarchical Grid?
Solution
By default, the hierarchy expand/collapse column in the Telerik UI for Blazor Grid is not declared in the markup like the other data-bound columns. It renders automatically when a DetailTemplate
is added to the Grid. At the time of writing (UI for Blazor 6.0.2), this built-in hierarchy expand/collapse column does not support being locked or other common configurations like managing its position, setting its width, or adding a title.
Vote for and follow the feature request for the Grid to support controlling the position of the expand column.
To customize the hierarchy expand/collapse column, follow these steps:
- Hide the default hierarchy expand column using custom CSS.
- Add another column with a template for expanding and collapsing the detail templates through the Grid state.
- Do not set
Field
for the column, so the data operations for this column (filtering, sorting, etc.) are disabled. - Toggle the icon in the custom hierarchy expand column based on the item's expanded state.
- Configure the custom hierarchy expand column. For example, set its order in the
GridColumns
declaration or enable theColumnMenu
to lock the column.
<TelerikGrid @ref="@GridRef"
Data="@GridData"
Pageable="true"
Sortable="true"
ShowColumnMenu="true"
FilterMode="@GridFilterMode.FilterMenu"
Class="no-default-hierarchy-column"
Width="600px">
<GridSettings>
<GridColumnMenuSettings ShowColumnChooser="false" />
</GridSettings>
<DetailTemplate>
@{
var employee = context as MainModel;
<TelerikGrid Data="employee.Orders" Pageable="true" PageSize="5">
<GridColumns>
<GridColumn Field="OrderId"></GridColumn>
<GridColumn Field="DealSize"></GridColumn>
</GridColumns>
</TelerikGrid>
}
</DetailTemplate>
<GridColumns>
<GridColumn Field="@nameof(MainModel.Id)" Width="60px"></GridColumn>
<GridColumn Field="@nameof(MainModel.Name)"></GridColumn>
<GridColumn Field="@nameof(MainModel.Address)"></GridColumn>
<GridColumn Field="@nameof(MainModel.Email)"></GridColumn>
<GridColumn Width="60px">
<Template>
@{
var dataItem = (MainModel)context;
}
<TelerikButton Icon="@GetButtonIcon(dataItem)" FillMode="@Telerik.Blazor.ThemeConstants.Button.FillMode.Flat" OnClick="@( () => OnButtonClick(dataItem) )" />
</Template>
</GridColumn>
</GridColumns>
</TelerikGrid>
<style>
/* shrink hierarchy column - do not hide it completely */
.no-default-hierarchy-column .k-hierarchy-col {
width: 0;
}
/* hide everything from hierarchy column */
.no-default-hierarchy-column .k-hierarchy-cell * {
display: none;
}
</style>
@code {
private TelerikGrid<MainModel>? GridRef { get; set; }
private List<MainModel> GridData { get; set; } = new List<MainModel>();
private async Task OnButtonClick(MainModel dataItem)
{
var gridState = GridRef.GetState();
if (gridState.ExpandedItems.Contains(dataItem))
{
gridState.ExpandedItems.Remove(dataItem);
}
else
{
gridState.ExpandedItems.Add(dataItem);
}
await GridRef.SetStateAsync(gridState);
}
private ISvgIcon GetButtonIcon(MainModel dataItem)
{
var gridState = GridRef.GetState();
return GetButtonIcon(gridState.ExpandedItems.Contains(dataItem));
}
private ISvgIcon GetButtonIcon(bool isExpanded)
{
if (isExpanded)
{
return SvgIcon.Minus;
}
else
{
return SvgIcon.Plus;
}
}
protected override void OnInitialized()
{
GridData = GenerateData();
}
private List<MainModel> GenerateData()
{
List<MainModel> data = new List<MainModel>();
for (int i = 0; i < 5; i++)
{
MainModel mdl = new MainModel { Id = i, Name = $"Name {i}", Address = $"Address {i}", Email = $"example{i}@mail.com" };
mdl.Orders = Enumerable.Range(1, 15).Select(x => new DetailsModel { OrderId = x, DealSize = x ^ i }).ToList();
data.Add(mdl);
}
return data;
}
public class MainModel
{
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string Email { get; set; }
public List<DetailsModel> Orders { get; set; }
//override the Equals() method of the Grid model to ensure the items are properly expanded in case their references are changed
public override bool Equals(object obj)
{
if (obj is MainModel)
{
return this.Id == (obj as MainModel).Id;
}
return false;
}
}
public class DetailsModel
{
public int OrderId { get; set; }
public double DealSize { get; set; }
}
}