最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c# - how to change page direction to RTL in radzen blazor studio app - Stack Overflow

programmeradmin0浏览0评论

I have a web application with radzen blazor studio. I added localization to the application. So it added CulturePicker.Razor page and CulturePicker.cs class.

This was the CulturePicker.cs class

<RadzenDropDown @bind-Value="@culture" TValue="string" Data="@(new [] { new { Text = "العربية (المملكة العربية السعودية)", Value = "ar-SA"}, new { Text = "English", Value = "en" } })"
    TextProperty="Text" ValueProperty="Value" Change="@ChangeCulture" />

and this is the [Change="@ChangeCulture"] method

protected void ChangeCulture()
{
    var redirect = new Uri(NavigationManager.Uri).GetComponents(UriComponents.PathAndQuery | UriComponents.Fragment, UriFormat.UriEscaped);

    var query = $"?culture={Uri.EscapeDataString(culture)}&redirectUri={redirect}";

    NavigationManager.NavigateTo("Culture/SetCulture" + query, forceLoad: true);
}

What I need is when the user changes the culture (language) the layout of the page (direction) change from RTL and LTR

I have a web application with radzen blazor studio. I added localization to the application. So it added CulturePicker.Razor page and CulturePicker.cs class.

This was the CulturePicker.cs class

<RadzenDropDown @bind-Value="@culture" TValue="string" Data="@(new [] { new { Text = "العربية (المملكة العربية السعودية)", Value = "ar-SA"}, new { Text = "English", Value = "en" } })"
    TextProperty="Text" ValueProperty="Value" Change="@ChangeCulture" />

and this is the [Change="@ChangeCulture"] method

protected void ChangeCulture()
{
    var redirect = new Uri(NavigationManager.Uri).GetComponents(UriComponents.PathAndQuery | UriComponents.Fragment, UriFormat.UriEscaped);

    var query = $"?culture={Uri.EscapeDataString(culture)}&redirectUri={redirect}";

    NavigationManager.NavigateTo("Culture/SetCulture" + query, forceLoad: true);
}

What I need is when the user changes the culture (language) the layout of the page (direction) change from RTL and LTR

Share Improve this question edited Nov 20, 2024 at 2:10 Tiny Wang 16.2k2 gold badges18 silver badges38 bronze badges asked Nov 19, 2024 at 17:07 Ibrahim-AmerIbrahim-Amer 192 bronze badges 9
  • According to this new release, we just need to add dir=”rtl” attribute to the html tag in your layout to enable right-to-left mode. May I know whether you've tried it? – Tiny Wang Commented Nov 20, 2024 at 2:24
  • I found a sample here which used ThemeService: blazor.radzen/theme-service?theme=material3&rtl=false – Tiny Wang Commented Nov 20, 2024 at 3:37
  • yes my friend i've tried. but the problem is if i but this code to mainlayout page the application starts in RTL which it shouldnot be , it should start in english culture with LTR layout. after the user select arabic language ( culture) the application changes to RTL layout. can you help me @Tiny Wang....... and my code in the other comment – Ibrahim-Amer Commented Nov 20, 2024 at 10:21
  • this is my code @Tiny Wang void SetDIR(string direction) { if (JSRuntime is IJSInProcessRuntime sr) sr.InvokeVoid("document.body.setAttribute", "dir", direction); else JSRuntime.InvokeVoidAsync("document.body.setAttribute", "dir", direction); } void SetRTL() => SetDIR("rtl"); void SetLTR() => SetDIR("ltr"); but when i call SetRTL on the method ChangeCulture It doesnot reponse – Ibrahim-Amer Commented Nov 20, 2024 at 10:24
  • Thanks a lot for your update but your codes can't work in my side as I don't have Culture/SetCulture component. Could you please comment NavigationManager.NavigateTo("Culture/SetCulture" + query, forceLoad: true); and call SetLTR() method to see whether it worked or not? In my side, I create a new blazor web app in VS and even if I don't have Radzon component library, it should work as well. – Tiny Wang Commented Nov 21, 2024 at 2:16
 |  Show 4 more comments

2 Answers 2

Reset to default 0

See my update below. I think it's somewhat ugly but it might be a workaround as it really work. I create a js method in App.razor component, which will call a .Net method. In the .Net method, it will change the direction of body element. Then when the culture dropdown option changed, it will change the direction to rlt, then a navigation will apply the change so that you will see it's chagned. If there's no navigation, you need to call SetRTL() method as well. I tried to use StateHasChanged() but it can't make the chagne applied. I tried to use Cascading parameter but I failed. I trust there will be a better solution but I've tried my best.

protected async Task ChangeCulture()
{
    await JS.InvokeVoidAsync("SetRtl");
    // SetRTL(); 
    _navigation.NavigateTo("/counter" + query, forceLoad: true);

}

<body dir="@CurrentDirection">
    <Routes />
    <script src="_framework/blazor.web.js"></script>
    <script src="_content/Radzen.Blazor/Radzen.Blazor.js?v=@(typeof(Radzen.Colors).Assembly.GetName().Version)"></script>
    <script>
        window.SetRtl = () => {
            DotNet.invokeMethodAsync('BlazorWebAppRadzen', 'changeDirection');
        }
    </script>

</body>
</html>

@code{
    public static string CurrentDirection = "ltr";

    [JSInvokable]
    public static void changeDirection()
    {
        CurrentDirection = "rtl";
    }
}

==============================

Firstly, I found radzen-blazor-components-v5 already support rtl appearence, the document mentioned

One of the most significant updates in this major version is the introduction of the highly anticipated Right-to-Left (RTL) support. All Radzen Blazor Components now fully support RTL direction .... To enable it, just add dir=”rtl” attribute to the html tag in your layout.

Following this action plan, I found this case which could work well in blazor app, no matter we used Radzen or not. I had a test with a new 8 blazor web app and adding codes below in Whether.razor component and it worked. You can also add the methods into your ChangeCulture method.

@page "/weather"
@attribute [StreamRendering]
@rendermode InteractiveServer
@inject IJSRuntime JS

<PageTitle>Weather</PageTitle>

<h1>Change Direction</h1>
<button @onclick=SetRTL>
    RTL
</button>
<button @onclick=SetLTR>
    LTR
</button>

@code {
    void SetDIR(string direction)
    {
        if (JS is IJSInProcessRuntime sr)
            sr.InvokeVoid("document.body.setAttribute", "dir", direction);
        else
            JS.InvokeVoidAsync("document.body.setAttribute", "dir", direction);
    }
    void SetRTL() => SetDIR("rtl");
    void SetLTR() => SetDIR("ltr");
}

Then I also found this sample using Radzen ThemeService. It requires to inject @inject ThemeService ThemeService and call ThemeService.SetRightToLeft({true/false}); to change the view.

Not sure if the original poster found a solution, but here is what I use for the same situation, and it works for me. It is configured to set the text direction based on the value of the culture cookie.

First, in the App.razor file, at the start of the code section, declare a string property called TextDirection, and set the value to match the direction of the text of the default website culture, so in my case, the default is en-IE so it is set to ltr:

private string TextDirection { get; set; } = "ltr";

Next, against the html opening tag, set the dir value to the previously created property

<html lang="en" dir="@TextDirection">

Finally, you need to add some logic to the OnInitialized method. Inside the if (HttpContext != null) logic, you need to declare a string to hold the text direction you will be setting the page to, default it to the default culture text direction. Next, you need to look for the .AspNetCore.Culture cookie and grab the value, it is does not exist, set it to the default culture of the website in this format - "c=en-IE|uic=en-IE". You then need to extract the culture from the cookie value into another variable, then, if the culture is rtl, set the text direction variable to rtl. Lastly, compare the text direction variable to the text direction property, and if they are different, set the property to the value of the variable:

protected override void OnInitialized()
{
    base.OnInitialized();

    if (HttpContext != null)
    {
        string cultureTextDir = "ltr";
        var cookieCulture = HttpContext.Request.Cookies[".AspNetCore.Culture"] ?? "c=en-IE|uic=en-IE";

        string culture = cookieCulture.Split('|').FirstOrDefault(part => part.StartsWith("c="))?.Substring(2);

        if (culture == "ar-AE")
        {
            cultureTextDir = "rtl";
        }

        if (TextDirection != cultureTextDir)
        {
            TextDirection = cultureTextDir;
        }

        var theme = HttpContext.Request.Cookies["BlankTemplateTheme"];

        if (!string.IsNullOrEmpty(theme))
        {
            ThemeService.SetTheme(theme, false);
        }
    }
}

If the culture cookie doesn't exist, then the default value is used. So, as long as you set the default values correctly, this should work. Also to note, in my example I check if the culture is ar-AE (United Arab Emirates) and if it is, the test direction is set to rtl, you can replace this with whatever logic you see fit for determining the text direction of the culture.

Below is the full page for reference:

@inject NavigationManager NavigationManager

<!DOCTYPE html>
<html lang="en" dir="@TextDirection">

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <base href="@NavigationManager.BaseUri" />
    <RadzenTheme @rendermode="@InteractiveServer" Theme="software" />
    <link rel="stylesheet" href="css/site.css" />
    <link rel="icon" href="favicon.ico" />
    <HeadOutlet @rendermode="@(new InteractiveServerRenderMode(prerender: false))" />
</head>

<body>
    <Routes @rendermode="@(new InteractiveServerRenderMode(prerender: false))" />
    <script src="_framework/blazor.web.js"></script>
    <script src="_content/Radzen.Blazor/Radzen.Blazor.js?v=@(typeof(Radzen.Colors).Assembly.GetName().Version)"></script>
</body>

</html>

@code {
    [CascadingParameter]
    private HttpContext HttpContext { get; set; }

    [Inject]
    private ThemeService ThemeService { get; set; }

    private string TextDirection { get; set; } = "ltr";

    protected override void OnInitialized()
    {
        base.OnInitialized();

        if (HttpContext != null)
        {
            string cultureTextDir = "ltr";
            var cookieCulture = HttpContext.Request.Cookies[".AspNetCore.Culture"] ?? "c=en-IE|uic=en-IE";

            string culture = cookieCulture.Split('|').FirstOrDefault(part => part.StartsWith("c="))?.Substring(2);

            if (culture == "ar-AE")
            {
                cultureTextDir = "rtl";
            }

            if (TextDirection != cultureTextDir)
            {
                TextDirection = cultureTextDir;
            }

            var theme = HttpContext.Request.Cookies["BlankTemplateTheme"];

            if (!string.IsNullOrEmpty(theme))
            {
                ThemeService.SetTheme(theme, false);
            }
        }
    }
}

Hope this helps.

发布评论

评论列表(0)

  1. 暂无评论