Hierarchical Data Grid using Lists

We want the ability to have a hierarchical grid that fetches the sub-grid (detail) data on demand (when row is expanded) . Our API returns Lists of objects. We are not using SfDataManager.  Upon expanding a row, method DetailDataBoundHandler ​is called and properly sets the UserApps collection from the returned list of objects. However, the expanded row shows no data. What is the proper way of doing this?


Attachment: code_db4dfed7.zip


12 Replies

RS Renjith Singh Rajendran Syncfusion Team January 14, 2022 06:49 AM UTC

Hi Dave, 
 
Greetings from Syncfusion support. 
 
We are not clear about the exact scenario you are facing the reported problem. We checked this scenario by creating a sample by populating child grid’s DataSource property value dynamically inside the DetailDataBound event handler. Child grid renders fine with data fetched inside DetailDataBound handler with the sample from our side. We are attaching the sample for your reference, please download and refer the sample from the link below, 
 
Kindly refer the above sample and if you are still facing difficulties then the following details would be helpful for us to proceed further. 
 
  1. Share a simple issue reproducing sample based on your scenario for us to validate.
  2. Or if possible reproduce the problem with the above attached sample and share with us for further analysis.
  3. Share a video showing the detailed explanation of the problem you are facing.
  4. Share the complete Grid rendering codes.
 
Note : We could not access the contents of the shared zip file. Kindly reattach/share the above requested details. 
 
Regards, 
Renjith R 



DA Dave replied to Renjith Singh Rajendran January 14, 2022 12:49 PM UTC

Just change the ZIP extension to TXT and you'll be able to view my code.



DA Dave replied to Renjith Singh Rajendran January 14, 2022 01:22 PM UTC

Renjith,

I figured out my issue.  In the DetailTemplate, I did NOT have my <GridColumn> surrounded by <GridColumns>.  ​Now everything works.  However, I'm facing another issue.  Although DetailDataBoundHandler, is properly retrieving the detailed data for each row, when I expand a row AFTER I have expanded another row, the previous rows detailed data is showing up in the current row.  However, when I collapse and then re-expand the current row, the proper data is shown.  How to I fix this?


Thanks, 

Dave




RS Renjith Singh Rajendran Syncfusion Team January 17, 2022 08:47 AM UTC

Hi David, 
 
Based on your scenario, we suggest you to access and fetch data inside the DetailTemplate itself instead of using DetailDataBound event handler. Please refer and use as like the code below, 
 
 
    <GridTemplates> 
        <DetailTemplate> 
            @{ 
                var Data = (context as EmployeeData); 
                Orders = _ForecastService.GetApps(Data.EmployeeID).GetAwaiter().GetResult(); 
                <SfGrid DataSource="@Orders"> 
                    <GridColumns> 
                        <GridColumn Field=@nameof(Order.OrderID) HeaderText="First Name" Width="110"> </GridColumn> 
                        <GridColumn Field=@nameof(Order.ShipCountry) HeaderText="Title" Width="110"></GridColumn> 
                    </GridColumns> 
                </SfGrid> 
            } 
        </DetailTemplate> 
    </GridTemplates> 


We have also prepared a sample based on this scenario for your convenience, please download and refer the sample from the link below, 
 
Please get back to us if you need further assistance. 
 
Regards, 
Renjith R 



DA Dave replied to Renjith Singh Rajendran January 17, 2022 03:20 PM UTC

Renjith,

Thank for your response.  I implemented what you suggested and I get an error : 

 Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]

      Unhandled exception rendering component: Cannot wait on monitors on this runtime.

System.PlatformNotSupportedException: Cannot wait on monitors on this runtime.


Error occurs on the bold line below: 

@{

InfUser infUser = (context as InfUser);

UserApps = _authService.GetApps(infUser.ID).GetAwaiter().GetResult();

<SfGrid....

}

Thanks



RS Renjith Singh Rajendran Syncfusion Team January 18, 2022 01:10 PM UTC

Hi David, 
 
We are not certain about the exact scenario you are facing the reported exception. In the sample from our previous update, we have used similar codes to call the async method GetApps from WeatherForecastService. But we could not face any exception when running the sample attached from our previous update. Kindly refer the sample attached from our previous update and modify your application accordingly. Kindly ensure to remove the data fetching codes inside DetailDataBound event handler also. 
 
If you are still facing difficulties then, we need the following details to further analyze this scenario and proceed further, kindly share with us the following details for better assistance. 
 
  1. Share the method definition codes of GetApps you are using.
  2. Share the complete Grid codes(updated) you are using.
  3. If possible reproduce the problem with the ample attached from our previous update and share with us for further analysis.
 
The provided information will help us analyze the problem, and provide you a solution as early as possible. 
 
Regards, 
Renjith R 



DA Dave replied to Renjith Singh Rajendran January 18, 2022 02:54 PM UTC

Renjith,

Attached are (2) files.  One representing the grid, the other file contains our service code.  The service code makes calls to our API via HttpClient.  I think the big difference between our code and your example code is that we are calling an asynchronous API.  Even when using GetAwaiter().GetResult() in the method GetAppRoles(int id), we still see the error.

Thanks


Attachment: code_78ebd134.zip


RS Renjith Singh Rajendran Syncfusion Team January 19, 2022 09:56 AM UTC

Hi David, 
 
Based on this scenario, we suggest you to use custom way of binding for the SfGrid inside DetailTemplate. Based on the Query property value, we have handled the data fetching for the corresponding DetailTemplate Grids inside ReadAsync method. We are attaching the sample for your reference, please download the sample from the link below, 
References :  
 
Please refer the codes below, 
 
 
    <GridTemplates> 
        <DetailTemplate> 
            @{ 
                EmployeeData Data = (context as EmployeeData); 
                <SfGrid TValue="Order" Query=@(new Query().AddParams("DetailData",Data.EmployeeID))> 
                    <SfDataManager AdaptorInstance="@typeof(CustomAdaptor)" Adaptor="Adaptors.CustomAdaptor"></SfDataManager> 
                    <GridColumns> 
                        <GridColumn Field=@nameof(Order.OrderID) HeaderText="First Name" Width="110"> </GridColumn> 
                        <GridColumn Field=@nameof(Order.ShipCountry) HeaderText="Title" Width="110"></GridColumn> 
                    </GridColumns> 
                </SfGrid> 
            } 
        </DetailTemplate> 
    </GridTemplates> 
 
@code{ 
    public class CustomAdaptor : DataAdaptor 
    { 
        public WeatherForecastService _ForecastService { get; set; } 
        public CustomAdaptor(WeatherForecastService ForecastService) 
        { 
            _ForecastService = ForecastService; 
        } 
        // Performs data Read operation 
        public override async Task<object> ReadAsync(DataManagerRequest dm, string key = null) 
        { 
            string val = dm.Params["DetailData"].ToString(); 
            IEnumerable<Order> DataSource = await _ForecastService.GetApps(Convert.ToInt32(val)); 
            ... 
       } 
    } 
    ... 
 
} 
 
Please get back to us if you need further assistance. 
 
Regards, 
Renjith R 



DA Dave January 19, 2022 05:43 PM UTC

Renjith,

Works perfectly!  Thanks for all your help :)



VN Vignesh Natarajan Syncfusion Team January 20, 2022 05:00 AM UTC

Hi David,  

Thanks for the update.  

We are glad to hear that you have resolved your query using our solution.  

Please get back to us if you have further queries.  

Regards, 
Vignesh Natarajan. 



DA Dave January 28, 2022 07:02 PM UTC

I've successfully implemented a CustomAdapter (see above) for my child grid.  I've also implemented editing, and have  OnActionBegin() & OnActionComplete() methods defined for the child grid.  How would I "refresh" the child grid following an edit.  After a "save", it seems that the ReadAsync() method of the CustomAdapter class is called BEFORE the OnActionComplete() method (this is where I'm retrieving the updated child row in our DB).  I'm doing the actual update of our the child grid row in our DB in the  OnActionBegin() method.


Thanks



RS Renjith Singh Rajendran Syncfusion Team January 31, 2022 07:22 AM UTC

Hi Dave, 
 
Query : I'm doing the actual update of our the child grid row in our DB in the  OnActionBegin() method. 
We suggest you to perform CRUD actions by overriding the corresponding CRUD methods(Insert/InsertAsync, Remove/RemoveAsync, Update/UpdateAsync) instead of using OnActionBegin event. When using custom way of binding you can customize the dataoperations and CRUD operations based on your requirement by overriding the CustomAdaptor methods(Insert/InsertAsync, Remove/RemoveAsync, Update/UpdateAsync and Read/ReadAsync). 
 
Query : BEFORE the OnActionComplete() method (this is where I'm retrieving the updated child row in our DB). 
We suggest you to retrieve the updated data from db inside Read/ReadAsync method of CustomAdaptor as like what we have performed in our previous update, instead of using OnActionComplete. 
 
Please use the above suggestion from your side instead of handling CRUD in OnActionBegin and fetching updated data inside OnActionComplete. Please get back to us if you need further assistance. 
 
Regards, 
Renjith R 
 


Loader.
Up arrow icon