radzenhq / radzen-blazor

Radzen Blazor is a set of 90+ free native Blazor UI components packed with DataGrid, Scheduler, Charts and robust theming including Material design and FluentUI.
https://www.radzen.com
MIT License
3.52k stars 785 forks source link

Add a `Culture` parameter on components for the default templates #206

Closed javiercampos closed 3 years ago

javiercampos commented 3 years ago

Is your feature request related to a problem? Please describe. When changing the Cutlure dynamically on a page (without reloading, thus, without changing the renderer thread's CurrentCulture/CurrentUICulture), you cannot reliably change the renderer's synchronization context Culture, so async calls (or InvokeAsync()) may have a different Culture.

I've made a feature request for Blazor to include this capability here: https://github.com/dotnet/aspnetcore/issues/35965

When you show the value or make binding yourself in the template you can use .ToString(MyCulture) or @bind-Value:culture="@MyCulture" if needed, but components like the RadzenDataGrid, or RadzenDropdown, etc., where you don't bind directly (instead, you specify a type and a property name), always use the thread's culture on their default templates, so if you want a different culture, you need to specify the whole Template for every column, or dropdown template, etc., which is really inconvenient.

Describe the solution you'd like Have a parameter on those components of type CultureInfo to specify the default culture on the component, e.g.: <RadzenDataGrid Culture="@MyCulture">, so that it takes it into account in the default templates (and it does .ToString(Culture) when rendering, instead of just ToString() -or nothing, which calls ToString with the CurrentUICulture format provider).

It could use CultureInfo.CurrentUICulture if not specified, so it would not break any existing code.

Additionally, default in-component templates for reflection-based rendered components (where you specify the type and the property name, instead of binding directly) would need to be revised to make use of that parameter.

akorchev commented 3 years ago

I think we won't implement this as there are supported ways to change the current culture in an ASP.NET Core application which work. Yes they require a reload but this is not such a big problem.

The Startup.cs file of the Sample application contains commented code which can be used to set the current application culture.

I have linked a screenshot showing this in action in this comment: https://github.com/radzenhq/radzen-blazor/pull/229#issuecomment-927694226

akorchev commented 3 years ago

This turned out to be a problem when certain conditions are met (static classes and events - more here. We are reopening the issue and will accept pull requests.

javiercampos commented 3 years ago

Thanks, I'll try to work on a PR, but can't make promises with the timeframe.

Would it be ok, if, apart from a Culture parameter I add a DefaultCulture cascading parameter? That way you could optionally set up a cascading value provider that would provide the culture to all descendant radzen components without having to specify it on each individual component (while you could also set the Culture individually on any component, should you wish to do that).

akorchev commented 3 years ago

Would it be ok, if, apart from a Culture parameter I add a DefaultCulture cascading parameter?

If it is not too much of a hassle - why not. It would probably require another property though ...

[Parameter]
public CultureInfo Culture { get; set; }

[CascadingParameter]
public CultureInfo DefaultCulture { get; set; }

CultureInfo CurrentCulture => Culture ?? DefaultCulture ?? CultureInfo.CurrentCulture;
javiercampos commented 3 years ago

@akorchev I've made a PR. Sorry but I don't typically contribute code to OSS and I'm not sure the guidelines for making one and if that's correct. If you want me to review or test anything (I've just ran the tests as they were), please tell me