Create custom rows in RadzenDataGrid

I am trying to add some custom rows into a datagrid as separator rows and also have one row at the top that remains static. I've been able to achieve this by inserting some "dummy" data into my collection and then adding some conditional logic in the CellRender callback but this seems like the wrong way to do this, especially when I want to add some sorting, filtering etc to my grid. Here's an image of what I'm trying to accomplish.

you can see just below the header, I have another row "Team Lead" followed by a row that I want to keep static which will always have a specific item from my object, then another row "Team Members" followed by my actual data set.

Is there a way to do this besides using the callback method and adding attributes to my table cell conditionally based on "fake" data inserted into my list?

In my opinion this DataGrid looks like grouped:

There is no way at the moment to hide the group expand/collapse button however we accept pull requests!

great! I've got a working model using groups now thanks. Is there a way (out of the box) to not show the property name that prefixes the group name? I need my "groups" to just show "Team Lead" and "Team Members" without the property name.

I'm sure I can work something up to remove the property name but if there's already a way to hide that, I'd prefer to just use baked in functionality.

edit: also, when I turn grouping on, it adds a colon to the column header titles, why is that and can those also not be shown?

edit again: I figured out how to remove the verticle elipses (not colons) by just setting "AllowGrouping" to false (seems a little counter intuitive to then do some grouping in the OnRender method, but I guess the AllowGrouping property is to allow users to drag and drop columns for further grouping). Still trying to figure out how I can hide the property name that is prefixing my group row w/o having to do some javascript magic.

thanks so much!

I did some digging on your github repo and looked at RazenDataGridGroupRow and was able to sort this out. For anyone else looking to do the same thing, GroupHeaderTemplate will take care of this.

<GroupHeaderTemplate Context="Group">
    <span>@Group.Data.Key</span>
</GroupHeaderTemplate>

I did indeed want the expand / collapse button removed for one of my groups and my design actually calls for the button to be placed on the right side of my grid in the group header row. I looked through the code to see if I could call the method to expand / collapse the group from a new button but all of the access modifiers for that process are internal so not available in my implementation code.

I was able to hide your toggle button through css but curious why you dedicated an entire column that has to span the whole grid for that button?

from what I could decipher reading the code, the gridview out of the box has a boolean property that can be toggled that expands / collapses all groups but there's no way to expand / collapse from implementation a single group with a custom process. Is that accurate? Was there a reason you didn't publically expose a the method that handles that? I'd be willing to create a PR to assist in improving this process by making individual groups collapsible with a custom implementation and making your implementation hideable but I'd like to understand why everything was set to internal before I dive into anything.

You can use GroupRowRender event to set if a group is expandable or not. Check the code of the demo I’ve posted.

I did check that already. Using args.Expanded works for collapsing the group but does not work for expanding the group after it has been collapsed.

The demo does exactly this when you press expand all groups button - will expand groups even if they were collapsed.

but that is by virtue of the gridview binding @bind-AllGroupsExpanded. It's not granular to trigger a group individually. I need to create my own implementation of your toggle button at the group level because I don't want the placement to the left of the group header. The boolean that you're switching in your demo just affects the binding for all groups.

Feel free to check the code of the component for reference.

for anyone interested, this is how I implemented it:

Updates to RadzenDataGrid

        [Parameter]
        public RenderFragment<(Group, RadzenDataGridGroupRow<TItem>)> GroupHeaderTemplate { get; set; }

// and make this method public

public async System.Threading.Tasks.Task ExpandGroupItem(RadzenDataGridGroupRow<TItem> item, bool? expandedOnLoad)

updates to RadzenDataGroupRow

@Grid.GroupHeaderTemplate((Group, this))

implementation:

    <GroupHeaderTemplate>
        <RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.SpaceBetween">
            <div>
                @context.Item1.Data.Key
            </div>
            @if (context.Item1.Data.Key == "Team Members")
            {
                <RadzenButton Click="(_ => TeamMembersParentGrid.ExpandGroupItem(context.Item2, false))" Text="Toggle" />
            }
        </RadzenStack>
    </GroupHeaderTemplate>

I cleaned up my implementation and wanted to share. @enchev, I'm happy to create a PR for this if you think it'd help others. Here's what I've changed.

updates to RadzenDataGrid.razor.cs

/// <summary>
/// Gets or sets the group header with option to add custom toggle visibility button template.
/// </summary>
/// <value>The group header template with option to add custom toggle visibility.</value>
[Parameter]
public RenderFragment<(Group Group, RadzenDataGridGroupRow<TItem> GroupHeader)> GroupHeaderToggleTemplate { get; set; }

// make this method public
public async System.Threading.Tasks.Task ExpandGroupItem(RadzenDataGridGroupRow<TItem> item, bool? expandedOnLoad)

/// <summary>
/// Gets or sets a value indicating whether to show default group toggle visibility column
/// </summary>
/// <value><c>true</c> if want to show left column with group visibility toggle, otherwise <c>false</c>.</value>
[Parameter]
public bool ShowGroupExpandColumn { get; set; } = true;

Updates to all components that render the table column with the default group visibility toggle. Only including one in this post as an example reference:

                                @if (ShowGroupExpandColumn)
                                {
                                    @foreach (var g in Groups)
                                    {
                                        <th class="rz-col-icon rz-unselectable-text" scope="col" rowspan=@(deepestChildColumnLevel + 1)>
                                            <span class="rz-column-title"></span>
                                        </th>
                                    }
                                }

updates to RadzenDataGridGroupRow.razor

<tr class="rz-group-row" @attributes="@rowArgs.Item2">
    @if (Grid.ShowGroupExpandColumn)
    {
        @if (Group.GroupDescriptor != null)
        {
            @for (var i = 0; i < GetLevel(); i++)
            {
                <td class="rz-col-icon">
                    <span class="rz-column-title"></span>
                </td>
            }

        }
    }
    @if (Grid.ShowGroupExpandColumn)
    {
        <td class="rz-col-icon">
            <span class="rz-column-title"></span>
            <a aria-label=@Grid.ExpandGroupAriaLabel @onclick:preventDefault="true" @onclick="@(_ => Grid.ExpandGroupItem(this, rowArgs.Item1.Expanded))">
                <span class="@(Grid.ExpandedGroupItemStyle(this, Grid.allGroupsExpanded != null ? Grid.allGroupsExpanded : rowArgs.Item1.Expanded))"></span>
            </a>
        </td>
    }
    <td colspan="@(TotalColumnCount + Grid.Groups.Count - 1 - Group.Level + (Grid.Template != null && Grid.ShowExpandColumn ? 1 : 0))">
        <span class="rz-cell-data">
            @if (Grid.GroupHeaderTemplate != null)
            {
                @Grid.GroupHeaderTemplate(Group)
            }
            else if (Grid.GroupHeaderToggleTemplate != null)
            {
                @Grid.GroupHeaderToggleTemplate((Group, this))
            }
            else if(Group.GroupDescriptor != null)
            {
                @(Group.GroupDescriptor.GetTitle() + ": " + GetKeyAsString())
            }
        </span>
    </td>
</tr>

implementation:

<RadzenDataGrid @ref="TeamMembersParentGrid"
                SelectionMode="DataGridSelectionMode.Multiple"
                Data="FilteredTeamMembers"
                TItem="TeamMember"
                AllowRowSelectOnRowClick="false"
                class="team-members-grid-view"
                @bind-Value="@_selectedTeamMembers"
                AllowGrouping="false"
                Render="@OnTeamMembersGridRender"
                ShowGroupExpandColumn="false">
    <GroupHeaderToggleTemplate Context="GroupedItems">
        <RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.SpaceBetween">
            <div>
                    @GroupedItems.Group.Data.Key
            </div>
                @if (@GroupedItems.Group.Data.Key == "Team Members")
            {
                <RadzenButton Click="(_ => TeamMembersParentGrid.ExpandGroupItem(GroupedItems.GroupHeader, false))" Text="Toggle" />
            }
        </RadzenStack>
    </GroupHeaderToggleTemplate>
....
</RadzenDataGrid>

Hi @Spock,

Sure, please submit pull request!

I just tried pushing my branch up to create the PR and it says I don't have permission and asked if I wanted to create a fork instead.

do you need to grant me permission first or is there a way to create a PR from a fork?

if you need to grant permission to my github account, my username is CodeProTv

nevermind, I figured out how to do it from a fork, I"ll get it created momentarily.

Thanks. Try to keep the original formatting and just add your code - at the moment there are lot of unrelated changes.

I noticed that as well, my IDE must've tried to magically change the formatting. I'm pretty sure it was from my linting tool. I'll try and disable that and update my PR.

turned my linter off, closed the first pull request, updated the code again and kept the original formatting and created a new PR.