Reputation: 266
I am still exploring what Blazor's QuickGrid can do.
And I faced one annoying problem here. I want to add one more column that will be used to render checkboxes in the header and in the body. I want this column to be rendered by providing only type parameter, like this:
<QuickGrid Data="@data">
<CheckboxColumn Title="Checkbox" /> // my custom column
<PropertyColumn Property="@(c => c.Id)" Format="C" />
<PropertyColumn Property="@(c => c.Name)" />
<TemplateColumn Title="Actions">
<button>@context.Price</button>
</TemplateColumn>
</QuickGrid>
From the docs we know that we may define columns by adding components derived from the ColumnBase<TGridItem> base class.
So, I created my custom class like this:
public class CheckboxColumn<TGridItem> : ColumnBase<TGridItem>
{
// abstract method implementation
}
The problem is that in the end, the grid doesn't renders my column (means that in the browser I can see all of the columns except the first one). Why?
Remarks:
Grid.AddColumn(this)
in the ColumnBase.razor
. But then, due to invoke of a callback, the grid re-renders, clears the collection of the columns, and renders @ChildContent
again, means that Grid.AddColumn(this)
gets called again. But this time, the first this
is the 2nd column.So, in short: on initial render we get all 4 columns -> at specific time re-rendering happens -> collection of columns gets cleared -> we get only 3 columns (all except the first one)
I hope you could follow the logic.
CheckboxColumn
is derived from ColumnBase
, we can use, for example, a HeaderTemplate
which is a RenderFragment<>
. If we provide something in the HeaderTemplate
for CheckboxColumn
-- everything renders fine. But I don't want to provide any RenderFragment
s in there.UPD-1
If Align
parameter is provided to CheckboxColumn
-- everything is fine! But it still doesn't answer the question for me...
UPD-2 If I am not mistaken, this statement (All of the parameters are from a set of known types† or any primitive type that hasn't changed since the previous set of parameters were set.
) answers, why my CheckboxColumn
does not get re-rendered. So how can I force re-render?
Upvotes: 3
Views: 7084
Reputation: 4151
I would like myself an empty column which I use for CSS index number but I believe it is not possible at the moment, due to current QuickGrid implementation so we have to do the ceremony for now 🤣.
I have created some bare minimum for you which works for me, two examples:
<EmptyColumn Title="#" TGridItem="CorporateUserDto" Property="new()" />
<EmptyColumn2 Title="#" Property="new()" />
The first one is passing the type TGridItem
, and so it is generic.
The second one has a hard coded type, which you will see below but must be the same type as your TGridItem otherwise it won't work.
public class EmptyColumn<TGridItem> : ColumnBase<TGridItem>
{
/// <summary>
/// Dummy Property otherwise it doesn't render
/// </summary>
[Parameter] public TGridItem? Property { get; set; }
protected override void CellContent(RenderTreeBuilder builder, TGridItem item)
=> builder.AddContent(0, “Hi”);
}
public class EmptyColumn2 : ColumnBase<CorporateUserDto>
{
/// <summary>
/// Dummy Property otherwise it doesn't render
/// </summary>
[Parameter] public CorporateUserDto? Property { get; set; }
protected override void CellContent(RenderTreeBuilder builder, CorporateUserDto item)
=> builder.AddContent(0, “Hello”);
}
Another example is this one, which is again flexible as I can select any boolean property I want so it is type checked.
<CheckboxColumn TGridItem="CorporateUserDto" Property="@(c => c.IsLondon)" />
I used this implementation for CheckboxColumn
, but because it is just boolean, it is simlified
https://github.com/aspnet/AspLabs/blob/main/src/QuickGrid/src/Microsoft.AspNetCore.Components.QuickGrid/Columns/PropertyColumn.cs
An alternative or combination with the custom columns is the flexibility to add them dynamically in the easiest way, e.g. using some manager e.g. we can add a column as simply as calling this AddSpaceshipId()
.
@code {
private bool _isLoading = true;
private List<SpaceshipDto> _items = new();
private ColumnManager<SpaceshipDto> _columnManager = new();
protected override async Task OnInitializedAsync()
{
_columnManager.AddSpaceshipId();
_columnManager.AddSpaceshipName();
_columnManager.Add(new() { Property = p => p.LastDepartureDate, Title = "Last Departure" });
_columnManager.Add(new() { Property = p => p.LastDepartureDays, Title = "Days", Align = Align.Center });
_items = await Service.GetSpaceships();
_isLoading = false;
}
}
And then we can render it here
<QuickGrid Items=“@_items.AsQueryable()” Class=“table table-sm table-index table-striped small table-blazor table-fit mb-0 table-thead-sticky” Theme=“earth”>
<EmptyColumn Title=“#” TGridItem=“SpaceshipDto” Property=“new()” />
@foreach (var col in _columnManager.Get())
{
<PropertyColumn Title=“@col.Title”
Property=“@col.Property”
Sortable=“@col.Sortable”
Align=“@col.Align” />
}
</QuickGrid>
I am preparing a blog post regarding the ColumnManager
. I will leave a link in the comment once it is done.
Upvotes: 0