Yes, we have done it the FilterTemplate way, but then we can't use the built in way of restoring the filters using the DataGridSettings and we have to read the column settings ourselves and set the selectedvalues manually.
We now have this setup
protected async Task LoadStateAsync()
{
try
{
await _semaphoreSlim.WaitAsync();
var (settings, isSuccess) = await SettingsService.GetSettingOrDefaultAsync<DataGridSettings>(GetType().FullName ?? string.Empty);
if (isSuccess && settings is not null)
{
try
{
_settings = settings;
var properties = GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).ToDictionary(t => t.Name);
foreach (var filterProperty in FilterRestoreProperties)
{
var column = _settings.Columns?.FirstOrDefault(c => c.Property == filterProperty.Key);
if (column?.FilterValue is null)
{
continue;
}
var filterPropertyInfo = properties.GetValueOrDefault(filterProperty.Value);
if (filterPropertyInfo is not null)
{
try
{
if (column.FilterValue is JsonElement jsonElement)
{
column.FilterValue = jsonElement.Deserialize(filterPropertyInfo.PropertyType);
filterPropertyInfo.SetValue(this, column.FilterValue);
}
else
{
filterPropertyInfo.SetValue(this, column.FilterValue);
}
}
catch
{
// Silently continue
}
}
}
}
catch (Exception ex)
{
_settings = new DataGridSettings();
}
}
else
{
_settings = new DataGridSettings();
}
}
finally
{
_semaphoreSlim.Release();
StateHasChanged();
}
}
You don't need to restore the values yourself. The context of FilterTemplate is the column, so bind your dropdown to the column instead of to a page field: read with context.GetFilterValue() and write with context.SetFilterValueAsync(...).
<RadzenDataGridColumn Property="Locatie" Title="Locatie" Type="typeof(IEnumerable<string>)"
FilterOperator="FilterOperator.In" LogicalFilterOperator="LogicalFilterOperator.Or">
<FilterTemplate>
<RadzenDropDown TValue="IEnumerable<string>" Data="@locaties" Multiple="true" Chips="true" AllowClear="true" Style="width:100%"
Value="@(context.GetFilterValue() as IEnumerable<string>)"
Change="@(args => context.SetFilterValueAsync(args is IEnumerable<string> v && v.Any() ? v : null))" />
</FilterTemplate>
</RadzenDataGridColumn>
With this setup everything goes through the built-in settings pipeline:
SetFilterValueAsync stores the value on the column, raises SettingsChanged and reloads the grid.
When the settings are loaded back (@bind-Settings or LoadSettings), the grid converts the saved FilterValue to the column type (the JSON array becomes a List<string> because of Type="typeof(IEnumerable<string>)"), calls SetFilterValue on the column, filters the data and re-renders. The template then simply reads the restored value from context.
No reflection or manual deserialization needed. If you need custom conversion for a special type you can override SetColumnFilterValueFromSettings on the grid instead.