You can enable the subgrids support for your grid. Subgrids allows to view records for those tables that have a 1 to N relationship with the parent table of the main grid.
We asume that you already configured the parent grid and it's working as expected as described in the Quick start section.
We have to add the subgrid column definition on code section of the same razor page we used to render the main grid. It must be an static object:
@code
{
...
public static Action<IGridColumnCollection<OrderDetail>> OrderDetailColumns = c =>
{
c.Add(o => o.OrderID);
c.Add(o => o.ProductID);
c.Add(o => o.Product.ProductName);
c.Add(o => o.Quantity).Format("{0:F}");
c.Add(o => o.UnitPrice).Format("{0:F}");
};
...
}
We have to add the following element on OnParametersSetAsync method of the same razor page we used to render the main grid:
protected override async Task OnParametersSetAsync()
{
...
Func<object[], Task<ICGrid>> subGrids = async keys =>
{
int orderId;
int.TryParse(keys[0].ToString(), out orderId);
var subGridQuery = new QueryDictionary<string>();
var subGridClient = new GridClient<OrderDetail>(q => gridClientService.GetOrderDetailsGrid(q, orderId), subGridQuery, false,
"orderDetailsGrid" + keys[0].ToString(), OrderDetailColumns, locale)
.Sortable()
.Filterable()
.SetStriped(true)
.WithMultipleFilters()
.WithGridItemsCount();
await subGridClient.UpdateGrid();
return subGridClient.Grid;
};
}
The new element is a function to create the subgrids. The parameter keys must be an array of objects that the function will use to create the required url for the back-end dRPC service. It's important to declare all variables needed by the contructor of the GridClient object inside the function block to avoid sharing parameters among subgrids.
Then we have to modify the GridClient we used to create the main grid adding a SubGrid method:
protected override async Task OnParametersSetAsync()
{
...
var client = new GridClient<Order>(gridClientService.GetOrdersGridRows, query, false, "ordersGrid", Columns, locale)
.Sortable()
.Filterable()
.SetStriped(true)
.WithMultipleFilters()
.WithGridItemsCount()
.SubGrid(subGrids, ("OrderID","OrderID"));
...
}
Parameter | Type | Description |
---|---|---|
subGrids | Func<object[], Task> | function that creates subgrids defined in the step before |
allOpended | bool (optional) | boolean to configure if all subgrids are opened or closed when the grid is initialized or updated. The default value is false. |
keys | params (string, string)[] | variable number of tuples of strings with the names of required columns to find records for the subgrid (foreign keys). The first value of the tuple is the name of property of the parent grid and the second value is the name of property of the child grid. |
Finally we have to add a method in the gRPC service to get rows for subgrids. An example of this type of method is:
-
in the Server project:
public async ValueTask<ItemsDTO<OrderDetail>> GetOrderDetailsGrid(Request request) { var orderDetails = (new OrderDetailsRepository(_context)).GetForOrder(request.Id); var server = new GridCoreServer<OrderDetail>(orderDetails, request.Query, false, "orderDetailsGrid" + request.Id.ToString(), ColumnCollections.OrderDetailColumns) .WithPaging(10) .Sortable() .Filterable() .WithMultipleFilters() .SetRemoveDiacritics<NorthwindDbContext>("RemoveDiacritics"); var items = await server.GetItemsToDisplayAsync(async x => await x.ToListAsync()); return items; }
-
in the Client project:
public async Task<ItemsDTO<OrderDetail>> GetOrderDetailsGrid(QueryDictionary<string> query, int orderId) { var handler = new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()); using (var channel = GrpcChannel.ForAddress(_baseUri, new GrpcChannelOptions() { HttpClient = new HttpClient(handler) })) { var service = channel.CreateGrpcService<IGridService>(); return await service.GetOrderDetailsGrid(new Request(orderId, query)); } }
Notes:
- This method must have ONLY 1 serializable parameter to avoid gRPC errors:
- a dictionary to pass query parameters such as grid-page. It must be of type
QueryDictionary<string>
. gRPC forces to use a dictionary of strings. All other protocols use a dictionary ofStringValues
, but gRPC does not serialize it by default. - it can be any other serializable object that includes
QueryDictionary<string>
as an attribute
- a dictionary to pass query parameters such as grid-page. It must be of type
- This method must have ONLY 1 serializable parameter to avoid gRPC errors:
Note that the grid name parameter we use must be unique for each subgrid. In this example we use the name "orderDetailsGrid" + OrderId.ToString()
.
<- Render button, checkbox, etc. in a grid cell | Passing grid state as parameter ->