I see what you are after however Blazor rendering is optimized by component type and to have full control of the render order of the components you need to use different composition for custom RadzenDataFilterProperty components - i.e. instead of different component types for each property type you can have single custom component type with different rendering depending on property type. For example:
MyRadzenDataFilterProperty.razor
@using Radzen
@typeparam TItem
@if (Type == typeof(bool))
{
<RadzenDataFilterProperty
TItem="TItem"
Property="@Property"
Title="@Title"
FilterOperator="FilterOperator.Equals"
Type="@typeof(bool)">
<FilterTemplate>
<RadzenDropDown Style="width:100%;"
AllowFiltering="false"
FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive"
Change="@(args => OnChange(args))"
@bind-Value="@context.FilterValue"
Data="@(new[] { true, false })"
AllowClear="true"
Multiple="false">
<Template Context="filterValue">
@{
var filterValueCasted = (bool)filterValue;
}
@if (filterValueCasted)
{
<span>Yes</span>
}
else
{
<span>No</span>
}
</Template>
<ValueTemplate Context="filterValue">
@{
var filterValueCasted = (bool)filterValue;
}
@if (filterValueCasted)
{
<span>Yes</span>
}
else
{
<span>No</span>
}
</ValueTemplate>
</RadzenDropDown>
</FilterTemplate>
</RadzenDataFilterProperty>
}
else
{
<RadzenDataFilterProperty TItem="TItem" Property="@Property" Title="@Title"/>
}
@code {
[Parameter]
public Type Type { get; set; }
[Parameter]
public string Property { get; set; }
[Parameter]
public string Title { get; set; }
[Parameter]
public EventCallback<bool> ValueChanged { get; set; }
private void OnChange(object value)
{
if (value is bool boolValue)
{
ValueChanged.InvokeAsync(boolValue);
}
}
}
Home.razor
@page "/"
@using Microsoft.AspNetCore.Components.Rendering
@using RadzenDataFilterSort.Model
<PageTitle>Home</PageTitle>
<RadzenCard>
<RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Render Fragment</RadzenText>
<RadzenDataFilter Auto="true"
TItem="VmUser"
Data="users"
AllowColumnFiltering="@true">
<Properties>
@RenderFilters()
</Properties>
</RadzenDataFilter>
</RadzenCard>
@code{
private List<VmUser> users = new List<VmUser>();
private RenderFragment RenderFilters()
{
IEnumerable<Tuple<string, string, Type, int>> filters = new List<Tuple<string, string, Type, int>>()
{
new Tuple<string, string, Type, int>(nameof(VmUser.FirstName), nameof(VmUser.FirstName), typeof(string), 0),
new Tuple<string, string, Type, int>(nameof(VmUser.LastName), nameof(VmUser.LastName), typeof(string), 1),
new Tuple<string, string, Type, int>(nameof(VmUser.Email), nameof(VmUser.Email), typeof(string), 2),
new Tuple<string, string, Type, int>(nameof(VmUser.UserName), nameof(VmUser.UserName), typeof(string), 6),
new Tuple<string, string, Type, int>(nameof(VmUser.IsActive), nameof(VmUser.IsActive), typeof(bool), 3),
new Tuple<string, string, Type, int>(nameof(VmUser.IsAdmin), nameof(VmUser.IsAdmin), typeof(bool), 4),
};
return __builder =>
{
<text>
@foreach (var item in filters.OrderBy(i => i.Item4))
{
<MyRadzenDataFilterProperty TItem="VmUser" Type="@item.Item3"
Property="@item.Item1" Title="@item.Item2"/>
}
</text>
};
}
}
The result:
Using such approach you have full flexibility what and where to render and again it's far more flexible compared to hardcoding order index values in 200+ component declarations. Next day you can decide to order the filters in descending alphabet order and you will be able to do it with the approach I've demonstrated.