Closed julienGrd closed 4 years ago
Thanks for contacting us @julienGrd
It looks like this is a question about how to use ASP.NET Core Blazor. While we do our best to look through all the issues filed here, to get a faster response we suggest posting your questions to StackOverflow using the asp.net-core-blazor tag.
The trick is to set the grid as a cascading value, and have your headers register themselves by calling a method on the grid.
I give an example of doing this that show how to create a tab control.
https://blazor-university.com/templating-components-with-renderfragements/creating-a-tabcontrol/
thanks @mrpmorris i begin to see the tricks !
but in my case, i have difficulty to transpose your example in my context.
My main problem is my template need to be render for each row, so i will add too many times the components is her parents. On the other way, with data empty, i don't have way to show the header...
my templates are generic too, it make the thing more tricky
so i change the logic to render the header on a classic way and then render the body manually by iterate on my items
I finally arrived to a quite good solution, i have only one problem left
this is my actual code
//on the caller
<Grid Items="this.Model.ListEnfantsSearch">
<Columns >
<GeckosGridColumn Header="Nom" T="@(Is.GeckosSL.EntityModel.Enfant)">
<Body Context="child" >
@child.NomPrenom
</Body>
</GeckosGridColumn>
</Columns>
the grid
<table class="table table-sm table-borderless @(TableClass ?? "")" id="@this.Id">
<thead class="@(StyleHeader ? "styled" : "no-styled")">
<tr>
<CascadingValue Value="this">
@(Columns)
</CascadingValue>
</tr>
</thead>
<tbody class="group-element @(Disabled ? "disabled": "")">
@if (Items != null)
{
@foreach (var item in this.Items)
{
<tr>
@foreach (var c in this.InternalColumns)
{
<td scope="col">@(c.Body(item))</td>
}
</tr>
}
}
</tbody>
</table>
[Parameter]
public RenderFragment Columns { get; set; }
public List<GeckosGridColumnViewModel<TableItem>> InternalColumns = new List<GeckosGridColumnViewModel<TableItem>>();
internal void AddColumn(GeckosGridColumnViewModel<TableItem> column)
{
InternalColumns.Add(column);
this.LaunchStateHasChanged();
}
and finally the Column component
<th>@this.Header</th>
[CascadingParameter]
private BaseGridComponent<T> Parent { get; set; }
[Parameter]
public RenderFragment<T> Body { get; set; }
[Parameter]
public string Header { get; set; }
protected override void OnInitialized()
{
if (Parent == null)
throw new ArgumentNullException(nameof(Parent));
Parent.AddColumn(this);
base.OnInitialized();
}
As you can see, i need to specify the type manually on the column (because i use the Context to specify a generic body), i would prefer the column retrieve the type of the grid container, i don't know how to make that, so if you have idea i take it !
thanks for your help !
I don't think that is currently possible. It would be good if Blazor would allow us to specify a [Parameter]
property type that is an Array of components like this - so we could then enforce generic types on the embedded children.
public class Grid<T> : ComponentBase
{
[ViewChildren]
public GridColumn<T>[] Columns { get; set; }
}
public class GridColumn<T> : ComponentBase
{
}
<Grid Data=People>
<Columns>
<Column>@context.Name</Column>
</Columns>
</Grid>
yeah i try different solution but impossible to make better than declare directly the type (i try some things like T="@(this.Model.ListEnfantsSearch.GetType().GetGenericArguments()[0])" but i ended with error in razor.g.cs generated file.
So for the moement i will keep my solution, it's too bad because im really close to a perfect solution.
It can be nice if blazor team make something like you propose.
i think the post can stay opened until a better solution arrived.
Thanks again for your help @mrpmorris , i will never ended this without you
@julienGrd perhaps you could create a new ticket as a feature request, requesting some way to define strongly-typed child content.
you are right, it's done (https://github.com/aspnet/AspNetCore/issues/17194), i close this one !
Hello guys, I try to implement un grid component but i meet a problem with the logic of blazor components.
I actually manage my grid like this
I want to change this for a column based system, like this
and on the grid component, iterate on the columns to first render the header and then iterate on the columns and item to render the table body.
I surprisely don't find example like this on internet and i don't find the good way to achieve that.
It sem its it possible because i find some example like this here : https://blazor.syncfusion.com/demos/Grid/DefaultFunctionalities, but unfortunately i don't have access to source code..
Do you have idea on how i can achieve that ?
Thanks for your help !