Help with datagrid grouping

I am really having a hard time with group footers in the datagrid. I have followed the example and just keep getting error. The code samples are great, but in some circumstances I just can't seem to see follow it. It would be great if you could send me an example in Radzen 2.82 that I could look at to see how this is accomplished.

Here are my parameters:

I have a table with rows that contain the first and last name of employees and 10 contact steps... step1, step2, step3, etc..., a date and a contact type (phone call, email, text message)

each step is a boolean true/false

I need to group each employee and have a group footer that counts the number of true values in each column. I will then filter them by date or date range (the easy part)

No matter how I set it up, I can't get it to work.

If you can help, that would be great!

PS I am just using a single page and the table is in ms sql server.

Can you post what is error? To have group footers you need to define GroupFooterTemplate for desired column(s) and group the DataGrid by dragging column headers or by using API. If you want to count the items in the group you can use the following expression:

context.Data.Items.Cast<YourType>().Count()


It's the api part I am having trouble with. I looked at the example and interpreted to what I need and obviously did not get it right. I don't want to drag the grouping column, I want to programmatically group it.

this is the code that I added to the razor.cs page.

IList crmtasks;
RadzenDataGrid recapGrid; (say recapGrid already exists)

    protected override async Task OnInitializedAsync() (say OnInitializeAsync is already used)
    {
        await base.OnInitializedAsync();

        crmtasks = CrmTask.Include("OwnerLname").ToList(); (says CrmTask does not have an option for include)
    }

    void OnRender(DataGridRenderEventArgs<CrmTask> args)
    {
        if (args.FirstRender)
        {
            args.Grid.Groups.Add(new GroupDescriptor() { Property = "OwnerLname"});
            StateHasChanged();
        }
    }

I'm just not sure if I am putting it in the right place. The demo has it as part of the razor page using @code

Every time I try to follow the demo I go down this rabbit hole...By Blazor experience (or .net in general) is limited and I continue to try to learn. My experience mostly comes from web forms and wpf, and visual basic.

I do better with examples vs trying to use courses, so hope you can help with this.

Thanks for your help!

Any help here is appreciated

We need more info as we don't know what you want to do. The code you have posted does not mean much without some additional context. For example what is CrmTask? Why do you call Include? What is OwnerLname?

I am trying to emulate the code in your example.

CrmTask is a table. It consists of a date (that doesn't matter except for filtering) Each row in CrmTask has OwnerFname and OwnerLname (First and last name of the person completing the task) and 10 steps...Step1Complete, Step2Complete, Step3Complete, etc. each of these columns is a boolean. I want to group by OwnerLname and count the number of true's for each column (step is complete = true) so that i have a group footer as follows:
Step1 Name Step2 Name Step3 Name etc...
OwnerLname (# of True) (# of True) (# of True) etc...

The code at the end of your group footer example is: (which is what I was trying to emulate, which is where I get the include from)

@code {
IList orders;
RadzenDataGrid ordersGrid;

protected override async Task OnInitializedAsync()
{
    await base.OnInitializedAsync();

    orders = dbContext.Orders.Include("Customer").Include("Employee").ToList();
}

void OnRender(DataGridRenderEventArgs<Order> args)
{
    if(args.FirstRender)
    {
        args.Grid.Groups.Add(new GroupDescriptor(){ Property = "Employee.LastName", Title = "Employee" });
        StateHasChanged();
    }
}

}

The group footer calculation isn't the problem, its the group footer API that actually groups the rows in the table I am having issues with.

For the most part, I can get what I need from your demo's, but in some cases, I can't figure out how your raw source translates to Radzen 2.xx

I learn by doing and going through some of the training and classes out there are excrutiating and I just don't learn that way.

Anyway if you can help, I am very appreciative. If it's beyond the scope of your support, I also understand. Either way I do enjoy using Radzen!

I don't understand what count the number of trues for each column means. A column has only one value. I don't think Radzen can do that out of the box.

This includes related entities because the group descriptor uses them in the demo ("Employee.LastName"). It is not needed in your case as the column you group by ("OwnerLname") is in the same table (CrmTask).

Let me show you what I have tried
Here is my datagrid (name = recapGrid)

This is the code I added to my razor.cs file:

   bool? groupsExpanded;
    IList<CrmTask> gridTask;
    RadzenDataGrid<CrmTask> recapGrid;

    void OnRender(DataGridRenderEventArgs<Recap> args)
    {
        if (args.FirstRender)
        {
            args.Grid.Groups.Add(new GroupDescriptor() { Title = "Staff", Property = "CrmTask.OwnerLname", SortOrder = SortOrder.Descending });
            StateHasChanged();
        }
    }

    void OnGroupRowRender(GroupRowRenderEventArgs args)
    {
        args.Expanded = groupsExpanded;
    }

Then I added the following to the groupheadertemplate:

@gridTask.GroupDescriptor.GetTitle(): gridTask.Data.Key ?? "")

Here is what I get

RadzenDataGrid recapGrid; (tells me that recapGrid already exists)

Also when I try to run it tells me that gridTask is inaccessible due to type.

I just want to get the grouping working, then I will worry about the group totals (which should fall into place once I have that)

Can you possibly show me where I am going wrong with this?

Radzen generates that for you. You don't need it.

You probably haven't assigned any event handler to the Render event of your DataGrid. You have to assign it via the Radzen property grid. Make it Ivoke method and pick OnRender and pass ${event}.

Ok, I have adjusted that and passed ${event} to OnRender in the Render Event.

I now get the following errors (similar to before)

dotnet: c:\AccelerateCrm\server\Pages\Recap.razor.designer.cs(111,30): error CS1503: Argument 1: cannot convert from 'Radzen.DataGridRenderEventArgs<AccelerateCrm.Models.ConData.CrmTask>' to 'Radzen.GroupRowRenderEventArgs' [c:\AccelerateCrm\server\AccelerateCrm.csproj]

c:\AccelerateCrm\server\Pages\Recap.razor(43,9): error CS0122: 'RecapComponent.gridTask' is inaccessible due to its protection level [c:\AccelerateCrm\server\AccelerateCrm.csproj]

Am I incorrectly setting the OnRender in the razor.cs as follows?

void OnRender(DataGridRenderEventArgs args) (Recap is the name of the page...not sure if that is right.

Also it is still telling me that 'RecapComponent.gridTask' is inaccessible due to its protection level [c:\AccelerateCrm\server\AccelerateCrm.csproj]

What event did you handle in Radzen? It seems to not be Render but something else. Can you show us a screenshot of the property grid? It should be Render.

Here is a quick example.

The datagrid is bound to the Product class.

  1. Custom method in partial file (groups by ProductName).

         void OnRender(DataGridRenderEventArgs<BlazorDataGridSelection.Models.Sample.Product> args)
         {
           if (args.FirstRender)
           {
             args.Grid.Groups.Add(new GroupDescriptor(){ Property = "ProductName", SortOrder = SortOrder.Descending });
             StateHasChanged();
           }
         }
    
  2. Handle the Render event of the DataGrid.

  3. The event handler implementation.

  4. End result.

what does the group header look like?

I mean, what is the code for the group header template look like...

GroupHeader was not set in my demo. As far as I understood you can't even get grouping to work so let's start with that.

Ok so to recap what I did. I created a application with sample data. I recreated exactly what you wrote for the partial, I set Render to invoke method OnRender and set args to ${event}

Amazing!!!! It worked.

So by looking at the example as a whole, I was focusing on the wrong parts and therefore getting errors that really had nothing to do with what I was actually trying to accomplish.

I rebuild the actual page I was trying to create, using these steps and it worked perfectly.

I really overcomplicated it and thank you very much for clarifying it. Grouping is definitely very easy to do, now that I see what I was doing wrong!!

Now I am on to creating a group footer for each of the columns I want to get data for.

Simply put I have 10 columns that each have a boolean that is either true or false.

In the group footer of each column I want to count only the number of times that column is true.

In your example, the code is as follows:

Group amount: @String.Format(new System.Globalization.CultureInfo("en-US"), "{0:C}", context.Data.Items.Cast().Sum(o => o.Freight))

I have only 2 questions that I can't seem to understand (again sorry for ignorance)

  1. I don't see the need for the globalization as I only want a count of true instances which is just basically an int result.

  2. Your example says context.Data.Items.Cast.Sum(o => o.Freight))

I am trying to adapt it as follows

@String.Format( "{0:F}", context.Data.Items.Cast().Count(o => o.EventStep1Complete == true))

CrmTask being the table class

I can't seem to figure out what context is (stupid I know) is it the App Name, Database Name, Grid Name...? I have tried many combinations, but none get me Data.Items.Cast....

This is my last question on this subject. I have also posted it on Stack Overflow and get so many conflicting answers that I still can't figure it out.

You have been so helpful, I am truly grateful for everyone and everything with Radzen!!!!

Try with ${data}.Data.Items instead of context.Data.Items. The context is the implicit name of Blazor template contexts. In Radzen we use ${data}.

ignore that last post, I forgot the cast<> with the proper class...

It works!!!!!

Grouping is amazing, I was able to accomplish exactly what I was looking for...

I had 2 last questions on this (I know I said I was done...but something else got me)

  1. Is there anyway to disable the expand/collapse toggle
  2. How can I make the datagrid always collapsed.
    I have looked at the demos and I see that I need to set up a method for the GroupRowCollapse or GroupRowExpand, but I don't want to do it by group, just all groups.

This is what it looks like

and here is what I want it to look like

Great Stuff though!!!

Check the grouping API example. It shows how to collapse all rows

void OnGroupRowRender(GroupRowRenderEventArgs args)
{
    if (args.FirstRender)
    {
        args.Expanded = false;
    }
}

Then you can use CSS to hide the toggle. Assign a class custom attribute to your DataGrid e.g. my-grid. Then add the following to the styles.css file of your application:

.my-grid .rz-row-toggler {
    display: none;
}

Yes, I did look at the grouping API, having a problem passing the arg in the GroupRowRender. I keep getting the following error:

dotnet: c:\AccelerateCrm\server\Pages\Recap.razor.designer.cs(133,30): error CS1503: Argument 1: cannot convert from 'bool?' to 'Radzen.GroupRowRenderEventArgs' [c:\AccelerateCrm\server\AccelerateCrm.csproj]