0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【C#/Avalonia UI】アラビア語対応でレイアウト崩壊に青ざめた話と、FlowDirection で一括反転させるスマートな実装

0
Last updated at Posted at 2026-10-18

こんにちは! 個人でWindows用キャプチャツール「ClickCapture」を開発している chilili kobo です。

英語や中国語など18言語の多言語対応を終え、「これでグローバル対応は完璧だ!」と調子に乗っていたところ、19番目の言語としてアラビア語を追加した瞬間にレイアウトが盛大に崩壊し、絶望したお話です。


1. アラビア語追加で直面した「RTLの壁」

アラビア語はもちろん1ミリも読めないため、AI翻訳で作ったリソースファイルをそのまま組み込みました。

文字自体はアラビア語に変わったものの、実行してみるとレイアウトが左基準(LTR)のままで、トグルスイッチやボタン配置が完全にチグハグになってしまいました。

ここでAIに指摘されて初めて気づいたのが、アラビア語などのRTL(Right-to-Left)言語では、文字だけでなくUIの配置自体を右から左へ鏡写しに反転させる必要があるという事実です。

「これ、XAMLのレイアウトを全部書き直さないといけないのでは……?」と一瞬本気で青ざめました。


2. 解決策:FlowDirection と共通スタイルで一括反転

幸い、Avalonia UIにはレイアウトの基準方向を切り替える FlowDirection プロパティが用意されています。

個別の画面ごとに指定するのではなく、App.axaml のグローバルスタイルで全Windowに一括適用するのが最もスマートです。

実装手順

① ViewModelでRTL判定プロパティを用意

現在のカルチャーがRTLかどうかを判定し、Avalonia.Media.FlowDirection を返す静的プロパティを定義します。

using System.Globalization;
using Avalonia.Media;
using CommunityToolkit.Mvvm.ComponentModel;

namespace MyApp.ViewModels;

public partial class MainViewModel : ObservableObject
{
    /// <summary>
    /// 現在のUICultureがRTL(右から左)かどうかを判定してFlowDirectionを返す
    /// </summary>
    public static FlowDirection WindowFlowDirection =>
        CultureInfo.CurrentUICulture.TextInfo.IsRightToLeft
            ? FlowDirection.RightToLeft
            : FlowDirection.LeftToRight;
}

② App.axaml のスタイルで全Windowへ一括適用

App.axaml の <Application.Styles> で Window セレクタを指定し、自動で FlowDirection が適用されるようにします。

<Application xmlns="https://github.com/avaloniaui"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:vm="using:MyApp.ViewModels"
             x:Class="MyApp.App"
             x:DataType="vm:MainViewModel"
             RequestedThemeVariant="Default">

    <Application.Styles>
        <FluentTheme />

        <!-- 💡 アプリ内のすべてのWindowに対してFlowDirectionを一括設定 -->
        <Style Selector="Window">
            <Setter Property="FlowDirection" Value="{x:Static vm:MainViewModel.WindowFlowDirection}" />
        </Style>
    </Application.Styles>

</Application>

③ 起動時のカルチャー設定(Program.cs)

設定ファイル等から読み込んだ言語コード(例: "ar")を、Avalonia起動前にスレッドへ適用します。

using System;
using System.Globalization;
using System.Threading;
using Avalonia;

namespace MyApp;

internal partial class Program
{
    [STAThread]
    public static void Main(string[] args)
    {
        // 設定ファイル等から言語コードを取得(例: "ar")
        string savedLanguageCode = "ar"; // 実際には設定からロード
        
        if (!string.IsNullOrEmpty(savedLanguageCode) && savedLanguageCode != "auto")
        {
            var culture = new CultureInfo(savedLanguageCode);
            Thread.CurrentThread.CurrentCulture = culture;
            Thread.CurrentThread.CurrentUICulture = culture;
        }

        BuildAvaloniaApp()
            .StartWithClassicDesktopLifetime(args);
    }

    public static AppBuilder BuildAvaloniaApp()
        => AppBuilder.Configure<App>()
            .UsePlatformDetect()
            .WithInterFont()
            .LogToTrace();
}


3. 適用結果:コード1行(一括スタイル)で完璧に反転

この設計を入れて再起動すると、個別のXAMLを一切書き換えることなく、タイトルやトグル、下部ボタンの並び(右から「フォルダ」「ライセンス」「終了」)が美しく鏡写しに反転しました!


おわりに

「アラビア語って右から読むんだ……」という無知からのスタートでしたが、Avalonia UIの FlowDirection と共通スタイルを組み合わせることで、レイアウトを一切崩すことなくスマートにRTL対応を完了させることができました。

……ただ、AIに頼りきりで翻訳したアラビア語のテキストが、現地の人から見て「おい、今すぐ全財産をよこせ」みたいな謎の誤訳になっていないかという一抹の恐怖だけは、今も残っています(笑)。

多言語対応でRTL言語に直面した方は、ぜひこの一括スタイルのアプローチを試してみてください!


🔗 関連リンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?