Building Reusable Blazor Components - Seeking Advice

Hi there,

I recently built a Blazor Server app using the Radzen master-detail data grid component (Blazor DataGrid Component - Hierarchy | Free UI Components by Radzen). To improve reusability, I'd like to turn this functionality into a custom Blazor component.

Your expertise would be greatly appreciated in understanding best practices for building reusable components, specifically:

Dynamic Data Columns: How can I structure the component to allow for flexible configuration of data columns through parameters, eliminating the need for manual RadzenDataGridColumns definition?
Parameterization for Behavior and Appearance: What are effective strategies to parameterize the component to control features like paging, sorting, and styling?

Currently, I populate the grid from a database and manually add columns. Ideally, I'd like to define columns through parameters.

I believe creating a reusable master-detail grid component would significantly enhance my development workflow. Any insights you can share would be incredibly valuable.

Thank you for your time and consideration.

<RadzenDataGrid @ref="_grid" AllowFiltering="true" AllowPaging="true" PageSize="20" AllowSorting="false" RowClick="RowClick" ExpandMode="DataGridExpandMode.Single"
                Data="@_ordersDto" TItem="OrderDto" EditMode="DataGridEditMode.Single" RowUpdate="@OnUpdateRow" RowCreate="@OnCreateRow" @bind-Value="@SelectedOrders"
                ShowExpandColumn="false" ShowPagingSummary="true" AllowColumnResize="true" >
<Template Context="order">
	<RadzenDataGrid @ref="_gridDetail" AllowFiltering="@(_detailToInsert == null)" AllowPaging="true" PageSize="5" AllowSorting="@(_detailToInsert == null)" Data="@order.OrderDetailsDto"
					TItem="OrderDetailDto" EditMode="DataGridEditMode.Multiple" RowUpdate="@OnUpdateRowDetail" RowCreate="@OnCreateRowDetail" AllowColumnResize="true"
										AllowColumnPicking="true" ShowPagingSummary="true" ColumnWidth="150px" Density="Density.Compact" >
		<Columns>

		<RadzenDataGridColumn TItem="OrderDetailDto" Property="Id" Title="Product ID" Frozen="true" OrderIndex="1"/>
		<RadzenDataGridColumn TItem="OrderDetailDto" Property="ProductCode" Title="Product  Code" OrderIndex="2"/>
		<RadzenDataGridColumn TItem="OrderDetailDto" Property="Warehouse" Title="Warehouse" OrderIndex="3"/>
		<RadzenDataGridColumn TItem="OrderDetailDto" Property="Currency" Title="Currency" OrderIndex="4"/>
		<RadzenDataGridColumn TItem="OrderDetailDto" Property="Quantity" Title="Quantity" OrderIndex="5"/>

		</Columns>
	</RadzenDataGrid>
</Template>
<Columns>
	<RadzenDataGridColumn TItem="OrderDto" Property="Id" Title="Order ID" Width="120px"/>
	<RadzenDataGridColumn TItem="OrderDto" Property="OrderDateTime" Title="Order Date" Width="200px" Filterable="false"/>        
	<RadzenDataGridColumn TItem="OrderDto" Property="Status" Title="Status" Width="100px"/>
		
</Columns>
</RadzenDataGrid>

@code {

	IQueryable<OrderDto?> _ordersDto;
	IQueryable<Order?> _order;
	RadzenDataGrid<OrderDto?> _grid;
	RadzenDataGrid<OrderDetailDto> _gridDetail;
	IList<OrderDto?> SelectedOrders { get; set; }
	OrderDetailDto? _detailToInsert;

	protected override async Task OnInitializedAsync()
	{
		_logger.LogInformation("************ Orders Preparing... ************");
		
		user = (await _authenticationStateProvider.GetAuthenticationStateAsync()).User;

		//userName = user.Identity.Name;
		if (!user.Identity.IsAuthenticated)
		{
			NavigationManager.NavigateTo("/Identity/Account/Login", false);
		}
		if (DataLoading)
		{
			return;
		}

		try
		{
			DataLoading = true;
			_order = ViewOrdersUseCase.Execute(user);
			_ordersDto = Mapper.ProjectTo<OrderDto>(_order);
			
		   
		}
		catch (Exception e)
		{
			_logger.LogError(e.Message);
			
		}
		finally
		{
			DataLoading = false;
		}
		SelectedOrders = new List<OrderDto?> { _ordersDto.FirstOrDefault() };
		
	}
}

This https://demos.radzen.com/datagrid-dynamic gives a fair working idea for defining dynamic columns.