大規模な.NETプロジェクトで多言語/グローバリゼーションを実装するための最良の方法


87

私はまもなく大規模なc#プロジェクトに取り組み、最初から多言語サポートを組み込みたいと考えています。私は遊んだことがあり、言語ごとに個別のリソースファイルを使用してそれを機能させることができ、次にリソースマネージャーを使用して文字列をロードします。

私が調べることができる他の良いアプローチはありますか?

回答:


91

リソースで別のプロジェクトを使用する

私はと現在のソリューション持つ、アウト経験からこれを言うことができる12件の 24 API、MVC、プロジェクトライブラリ(コア機能)、WPF、UWPとXamarinが含まれるプロジェクトを。この長い投稿を読むのが最善の方法だと思うので、読む価値があります。VSツールを使用すると、簡単にエクスポートおよびインポートして、翻訳会社に送信したり、他の人がレビューしたりできます。

編集02/2018:引き続き強力であり、.NET Standardライブラリに変換すると、.NETFrameworkとNETCore全体で使用することも可能になります。たとえばangularが使用できるように、JSONに変換するためのセクションを追加しました。

編集2019: Xamarinを使用して、これはすべてのプラットフォームで引き続き機能します。たとえば、resxファイルも使用するためのXamarin.Formsのアドバイス。(私はまだXamarin.Formsでアプリを開発していませんが、ドキュメント、つまり開始するための詳細な方法で、Xamarin.Formsドキュメントで説明しています)。JSONに変換するのと同じように、Xamarin.Androidの.xmlファイルに変換することもできます。

編集2019(2): WPFからUWPにアップグレードしているときに、UWPで別のファイルタイプを使用することを好むことに気付きました.resw。これは、コンテンツは同じですが、使用法が異なります。私の意見では、これを行う別の方法を見つけました。これは、デフォルトのソリューションよりもうまく機能します

2020年の編集:複数の言語のプロジェクトを必要とする可能性のある大規模な(モジュラー)プロジェクトのいくつかの提案を更新しました。

だから、それに取り掛かろう。

プロの

  • ほとんどどこでも強くタイプされます。
  • WPFでは、を処理する必要はありませんResourceDirectories
  • 私がテストした限り、ASP.NET、クラスライブラリ、WPF、Xamarin、.NET Core、.NETStandardでサポートされています。
  • 追加のサードパーティライブラリは必要ありません。
  • カルチャフォールバックをサポート:en-US-> en。
  • バックエンドだけでなく、WPFの場合はXAML、MVCの場合は.cshtmlのXamarin.Formsでも機能します。
  • を変更することで言語を簡単に操作できます Thread.CurrentThread.CurrentCulture
  • 検索エンジンはさまざまな言語でクロールでき、ユーザーは言語固有のURLを送信または保存できます。

コンズ

  • WPF XAMLはバグがある場合があり、新しく追加された文字列は直接表示されません。再構築は一時的な修正です(vs2015)。
  • UWP XAMLは、インテリセンスの提案を表示せず、設計中にテキストを表示しません。
  • 教えてください。

セットアップ

ソリューションで言語プロジェクトを作成し、MyProject.Languageのような名前を付けます。Resourcesというフォルダーをそのフォルダーに追加し、そのフォルダーに2つのResourcesファイル(.resx)を作成します。1つはResources.resxと呼ばれ、もう1つはResources.en.resx(または特定の場合は.en-GB.resx)と呼ばれます。私の実装では、デフォルト言語としてNL(オランダ語)言語を使用しているため、これが最初のファイルに含まれ、英語が2番目のファイルに含まれます。

セットアップは次のようになります。

言語設定プロジェクト

Resources.resxのプロパティは次のとおりである必要があります。 プロパティ

カスタムツールの名前空間がプロジェクトの名前空間に設定されていることを確認してください。この理由は、WPFではResourcesXAMLの内部を参照できないためです。

そして、リソースファイル内で、アクセス修飾子をPublicに設定します。

アクセス修飾子

このような大規模なアプリケーション(たとえば、異なるモジュール)がある場合は、上記のように複数のプロジェクトを作成することを検討できます。その場合、キーとリソースクラスの前に特定のモジュールを付けることができます。Visual Studioに最適な言語エディターを使用して、すべてのファイルを1つの概要に結合します。

別のプロジェクトで使用する

プロジェクトへの参照:[参照]-> [参照の追加]-> [Prjects \ Solutions]を右クリックします。

ファイルで名前空間を使用します。 using MyProject.Language;

バックエンドでそのように使用し string someText = Resources.orderGeneralError; ます。Resourcesと呼ばれるものが他にある場合は、名前空間全体に配置します。

MVCでの使用

MVCでは、言語を設定することはできますが、パラメーター化されたURLを使用しました。これは、次のように設定できます。

RouteConfig.cs 他のマッピングの下

routes.MapRoute(
    name: "Locolized",
    url: "{lang}/{controller}/{action}/{id}",
    constraints: new { lang = @"(\w{2})|(\w{2}-\w{2})" },   // en or en-US
    defaults: new { controller = "shop", action = "index", id = UrlParameter.Optional }
);

FilterConfig.cs(追加する必要がある場合があります。追加する場合FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);は、のApplication_start()メソッドに追加します。Global.asax

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new ErrorHandler.AiHandleErrorAttribute());
        //filters.Add(new HandleErrorAttribute());
        filters.Add(new LocalizationAttribute("nl-NL"), 0);
    }
}

LocalizationAttribute

public class LocalizationAttribute : ActionFilterAttribute
{
    private string _DefaultLanguage = "nl-NL";
    private string[] allowedLanguages = { "nl", "en" };

    public LocalizationAttribute(string defaultLanguage)
    {
        _DefaultLanguage = defaultLanguage;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        string lang = (string) filterContext.RouteData.Values["lang"] ?? _DefaultLanguage;
        LanguageHelper.SetLanguage(lang);
    }
}

LanguageHelperは、カルチャ情報を設定するだけです。

//fixed number and date format for now, this can be improved.
public static void SetLanguage(LanguageEnum language)
{
    string lang = "";
    switch (language)
    {
        case LanguageEnum.NL:
            lang = "nl-NL";
            break;
        case LanguageEnum.EN:
            lang = "en-GB";
            break;
        case LanguageEnum.DE:
            lang = "de-DE";
            break;
    }
    try
    {
        NumberFormatInfo numberInfo = CultureInfo.CreateSpecificCulture("nl-NL").NumberFormat;
        CultureInfo info = new CultureInfo(lang);
        info.NumberFormat = numberInfo;
        //later, we will if-else the language here
        info.DateTimeFormat.DateSeparator = "/";
        info.DateTimeFormat.ShortDatePattern = "dd/MM/yyyy";
        Thread.CurrentThread.CurrentUICulture = info;
        Thread.CurrentThread.CurrentCulture = info;
    }
    catch (Exception)
    {

    }
}

.cshtmlでの使用法

@using MyProject.Language;
<h3>@Resources.w_home_header</h3>

または、用途を定義したくない場合は、名前空間全体に入力するか、/ Views /web.configで名前空間を定義できます。

<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
  <namespaces>
    ...
    <add namespace="MyProject.Language" />
  </namespaces>
</pages>
</system.web.webPages.razor>

このMVC実装ソースチュートリアル:素晴らしいチュートリアルブログ

モデルのクラスライブラリでの使用

バックエンドでの使用は同じですが、属性で使用するための単なる例です

using MyProject.Language;
namespace MyProject.Core.Models
{
    public class RegisterViewModel
    {
        [Required(ErrorMessageResourceName = "accountEmailRequired", ErrorMessageResourceType = typeof(Resources))]
        [EmailAddress]
        [Display(Name = "Email")]
        public string Email { get; set; }
    }
}

リシェーパーがある場合は、指定されたリソース名が存在するかどうかが自動的にチェックされます。型安全性を好む場合は、T4テンプレートを使用して列挙を生成できます

WPFでの使用。

もちろん、MyProject.Language名前空間への参照を追加します。これは、バックエンドでの使用方法を知っています。

XAMLで、WindowまたはUserControlのヘッダー内に、次のlangように呼ばれる名前空間参照を追加します。

<UserControl x:Class="Babywatcher.App.Windows.Views.LoginView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:MyProject.App.Windows.Views"
              xmlns:lang="clr-namespace:MyProject.Language;assembly=MyProject.Language" <!--this one-->
             mc:Ignorable="d" 
            d:DesignHeight="210" d:DesignWidth="300">

次に、ラベル内:

    <Label x:Name="lblHeader" Content="{x:Static lang:Resources.w_home_header}" TextBlock.FontSize="20" HorizontalAlignment="Center"/>

強く型付けされているので、リソース文字列が存在することを確認できます。セットアップ中にプロジェクトを再コンパイルする必要がある場合があります。WPFは新しい名前空間でバグがある場合があります。

WPFのもう1つのことは、内に言語を設定することApp.xaml.csです。独自の実装を行うか(インストール時に選択)、システムに決定させることができます。

UWPでの使用

UWPでは、Microsoftはこのソリューションを使用します。つまり、新しいリソースファイルを作成する必要があります。さらにx:Uid、XAMLのコントロールのをリソースのキーに設定するように求められているため、テキストを再利用することもできません。そして、あなたのリソースではExample.TextTextBlockのテキストを埋めるためにあなたがしなければなりません。リソースファイルを再利用したいので、そのソリューションはまったく好きではありませんでした。最終的に私は次の解決策を思いついた。今日(2019-09-26)にこれを見つけたので、これが期待どおりに機能しないことが判明した場合は、別の何かを返す可能性があります。

これをプロジェクトに追加します。

using Windows.UI.Xaml.Resources;

public class MyXamlResourceLoader : CustomXamlResourceLoader
{
    protected override object GetResource(string resourceId, string objectType, string propertyName, string propertyType)
    {
        return MyProject.Language.Resources.ResourceManager.GetString(resourceId);
    }
}

これをApp.xaml.csコンストラクターに追加します。

CustomXamlResourceLoader.Current = new MyXamlResourceLoader();

アプリ内のどこでも、これを使用して言語を変更します。

ApplicationLanguages.PrimaryLanguageOverride = "nl";
Frame.Navigate(this.GetType());

UIを更新するには、最後の行が必要です。私はまだこのプロジェクトに取り組んでいる間に、これを2回行う必要があることに気づきました。ユーザーが最初に起動するときに、言語を選択してしまう可能性があります。ただし、これはWindowsストア経由で配布されるため、通常、言語はシステム言語と同じです。

次に、XAMLで使用します。

<TextBlock Text="{CustomResource ExampleResourceKey}"></TextBlock>

Angularでの使用(JSONへの変換)

今日では、Angularのようなフレームワークをコンポーネントと組み合わせて使用​​することが一般的になっているため、cshtmlは使用していません。翻訳はjsonファイルに保存されます。これがどのように機能するかについては説明しません。角度のある複数翻訳ではなく、ngx-translateを強くお勧めします。したがって、翻訳をJSONファイルに変換する場合は、非常に簡単です。リソースファイルをjsonファイルに変換するT4テンプレートスクリプトを使用します。いくつかの変更を行う必要があるため、構文を読み取って正しく使用するには、T4エディターをインストールすることをお勧めします。

注意すべきことは1つだけです。データを生成、コピー、クリーンアップして、別の言語用に生成することはできません。したがって、以下のコードを使用している言語の数だけコピーし、「//ここで言語を選択」の前にエントリを変更する必要があります。現在、これを修正する時間はありませんが、おそらく後で更新されます(興味がある場合)。

パス:MyProject.Language / T4 / CreateLocalizationEN.tt

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="System.Windows.Forms" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Resources" #>
<#@ import namespace="System.Collections" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.ComponentModel.Design" #>
<#@ output extension=".json" #>
<#


var fileNameNl = "../Resources/Resources.resx";
var fileNameEn = "../Resources/Resources.en.resx";
var fileNameDe = "../Resources/Resources.de.resx";
var fileNameTr = "../Resources/Resources.tr.resx";

var fileResultName = "../T4/CreateLocalizationEN.json";//choose language here
var fileResultPath = Path.Combine(Path.GetDirectoryName(this.Host.ResolvePath("")), "MyProject.Language", fileResultName);
//var fileDestinationPath = "../../MyProject.Web/ClientApp/app/i18n/";

var fileNameDestNl = "nl.json";
var fileNameDestEn = "en.json";
var fileNameDestDe = "de.json";
var fileNameDestTr = "tr.json";

var pathBaseDestination = Directory.GetParent(Directory.GetParent(this.Host.ResolvePath("")).ToString()).ToString();

string[] fileNamesResx = new string[] {fileNameEn }; //choose language here
string[] fileNamesDest = new string[] {fileNameDestEn }; //choose language here

for(int x = 0; x < fileNamesResx.Length; x++)
{
    var currentFileNameResx = fileNamesResx[x];
    var currentFileNameDest = fileNamesDest[x];
    var currentPathResx = Path.Combine(Path.GetDirectoryName(this.Host.ResolvePath("")), "MyProject.Language", currentFileNameResx);
    var currentPathDest =pathBaseDestination + "/MyProject.Web/ClientApp/app/i18n/" + currentFileNameDest;
    using(var reader = new ResXResourceReader(currentPathResx))
    {
        reader.UseResXDataNodes = true;
#>
        {
<#
            foreach(DictionaryEntry entry in reader)
            {
                var name = entry.Key;
                var node = (ResXDataNode)entry.Value;
                var value = node.GetValue((ITypeResolutionService) null); 
                 if (!String.IsNullOrEmpty(value.ToString())) value = value.ToString().Replace("\n", "");
                 if (!String.IsNullOrEmpty(value.ToString())) value = value.ToString().Replace("\r", "");
#>
            "<#=name#>": "<#=value#>",
<#

    
            }
#>
        "WEBSHOP_LASTELEMENT": "just ignore this, for testing purpose"
        }
<#
    }
    File.Copy(fileResultPath, currentPathDest, true);
}


#>

modulairアプリケーションがあり、複数の言語プロジェクトを作成するという私の提案に従った場合は、それぞれにT4ファイルを作成する必要があります。jsonファイルが論理的に定義されていることを確認してください。論理的に定義する必要はありません。en.jsonまた、定義することもできますexample-en.jsonngx-translateで使用するために複数のjsonファイルを組み合わせるには、こちらの手順に従ってください

Xamarin.Androidで使用

上記のアップデートで説明したように、私はAngular / JSONで行ったのと同じ方法を使用します。しかし、AndroidはXMLファイルを使用するので、それらのXMLファイルを生成するT4ファイルを作成しました。

パス:MyProject.Language / T4 / CreateAppLocalizationEN.tt

#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="System.Windows.Forms" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Resources" #>
<#@ import namespace="System.Collections" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.ComponentModel.Design" #>
<#@ output extension=".xml" #>
<#
var fileName = "../Resources/Resources.en.resx";
var fileResultName = "../T4/CreateAppLocalizationEN.xml";
var fileResultRexPath = Path.Combine(Path.GetDirectoryName(this.Host.ResolvePath("")), "MyProject.Language", fileName);
var fileResultPath = Path.Combine(Path.GetDirectoryName(this.Host.ResolvePath("")), "MyProject.Language", fileResultName);

    var fileNameDest = "strings.xml";

    var pathBaseDestination = Directory.GetParent(Directory.GetParent(this.Host.ResolvePath("")).ToString()).ToString();

    var currentPathDest =pathBaseDestination + "/MyProject.App.AndroidApp/Resources/values-en/" + fileNameDest;

    using(var reader = new ResXResourceReader(fileResultRexPath))
    {
        reader.UseResXDataNodes = true;
        #>
        <resources>
        <#

                foreach(DictionaryEntry entry in reader)
                {
                    var name = entry.Key;
                    //if(!name.ToString().Contains("WEBSHOP_") && !name.ToString().Contains("DASHBOARD_"))//only include keys with these prefixes, or the country ones.
                    //{
                    //  if(name.ToString().Length != 2)
                    //  {
                    //      continue;
                    //  }
                    //}
                    var node = (ResXDataNode)entry.Value;
                    var value = node.GetValue((ITypeResolutionService) null); 
                     if (!String.IsNullOrEmpty(value.ToString())) value = value.ToString().Replace("\n", "");
                     if (!String.IsNullOrEmpty(value.ToString())) value = value.ToString().Replace("\r", "");
                     if (!String.IsNullOrEmpty(value.ToString())) value = value.ToString().Replace("&", "&amp;");
                     if (!String.IsNullOrEmpty(value.ToString())) value = value.ToString().Replace("<<", "");
                     //if (!String.IsNullOrEmpty(value.ToString())) value = value.ToString().Replace("'", "\'");
#>
              <string name="<#=name#>">"<#=value#>"</string>
<#      
                }
#>
            <string name="WEBSHOP_LASTELEMENT">just ignore this</string>
<#
        #>
        </resources>
        <#
        File.Copy(fileResultPath, currentPathDest, true);
    }

#>

Androidはvalues-xxフォルダーで動作するため、上記はフォルダー内の英語用values-enです。ただし、valuesフォルダに入るデフォルトも生成する必要があります。上記のT4テンプレートをコピーして、上記のコードのフォルダーを変更するだけです。

これで、すべてのプロジェクトに1つのリソースファイルを使用できるようになりました。これにより、すべてをexclドキュメントにエクスポートし、誰かがそれを翻訳して再度インポートできるようにすることが非常に簡単になります。

ファイルで素晴らしい働きをするこの素晴らしいVS拡張機能に特に感謝しresxます。彼の素晴らしい仕事のために彼に寄付することを検討てください(私はそれとは何の関係もありません、私はただ拡張機能が大好きです)。


1. Mylanguageにリソースを追加し、再コンパイルしてから再デプロイすることにより、デプロイ後にどのように言語を追加しますか?(2)翻訳に使用したIDEまたはツールはありますか(winformには40を超えるフォームがあります)、共有できますか?(3)試してみましたが、文化をアラビア語に変更しても翻訳が得られませんでした。質問を作成してお知らせします
Smith

5
1:Resources.xx.resxを複製してxxを変更し、switchステートメントがあるすべての場所で言語を追加します。2 ResxManager(TomEnglertによる)拡張機能を使用します。[ツール]-> [拡張機能]からインストールできます。言語を並べて表示するのに便利ですが、実際の翻訳は他の人が行います(ResxManagerを使用してExcelとの間で簡単にエクスポートおよびインポートできます)。3.前回も1つ追加して遭遇しました。上記のすべてのファイルを確認しますが、いくつかのブレークポイントを確認します。ただし、これはWinFormsでは使用しませんでした。
CularBytes 2018年

13
自分の答えに賛成できますか?WPFで言語を切り替えるバグを修正するために、自分の答えを愚かにチェックする必要がありました-.-
CularBytes 2018

1
@TiagoBrenckこんにちは、この特定の状況でのみ、英語がデフォルトの言語である場合は、resources.en-gb.resxファイルを作成し、そこに1%の変更を追加できます。デフォルトでは、言語en-gbが選択されていて単語が翻訳されていない場合、デフォルトの言語(resources.resx)が使用されます。
CularBytes 2018

1
リソースファイルのキーをどのように構成しましたか?リソースファイルを1つしか使用しておらず、巨大なアプリを使用しているとのことですが、どのようにキーを分割しましたか?「Feature.MyMessage」や「Area.Feature.MyMessage」のようなもの
FrancescoVenturini19年

21

さまざまなアプローチを使用して実装されたプロジェクトを見てきましたが、それぞれに長所と短所があります。

  • 1つは設定ファイルでそれをしました(私のお気に入りではありません)
  • データベースを使用してそれを行いました-これはかなりうまくいきましたが、何を維持するかを知っているのは苦痛でした。
  • ある人はあなたが提案している方法でリソースファイルを使用しました、そして私はそれが私のお気に入りのアプローチであったと言わなければなりません。
  • 最も基本的なものは、文字列でいっぱいのインクルードファイルを使用してそれを行いました-醜い。

選択したリソース方法は非常に理にかなっていると思います。このようなことをするより良い方法があるかどうか私はしばしば疑問に思うので、他の人の答えを見るのも面白いでしょう。私は、ここSOにあるものを含め、すべてがリソースの使用方法を指している多数のリソースを見てきました。


5

「最善の方法」はないと思います。それは本当にあなたが構築しているテクノロジーとアプリケーションのタイプに依存します。

Webappsは、他の投稿者が示唆しているようにデータベースに情報を保存できますが、別のリソースファイルを使用することをお勧めします。これは、ソースとは別のリソースファイルです。リソースファイルを分離すると、同じファイルの競合が減り、プロジェクトが大きくなるにつれて、ローカリゼーションがビジネスロジックとは別に行われることがあります。(プログラマーと翻訳者)。

Microsoft WinFormおよびWPFの専門家は、ロケールごとにカスタマイズされた個別のリソースアセンブリを使用することをお勧めします。

UI要素をコンテンツに合わせてサイズ変更するWPFの機能により、必要なレイアウト作業が軽減されます。例:(日本語の単語は英語よりもはるかに短い)。

WPFを検討している場合:このmsdnの記事読むことをお勧めします。正​​直に言うと、WPFローカリゼーションツールであるmsbuild、locbaml(およびExcelスプレッドシート)を使用するのは面倒ですが、機能します。

わずかに関連するもの:私が直面する一般的な問題は、エラーコードではなく、エラーメッセージ(通常は英語)を送信するレガシーシステムを統合することです。これにより、レガシーシステムへの変更が強制されるか、バックエンド文字列が自分のエラーコードにマッピングされてから、ローカライズされた文字列にマッピングされます...そうです。 エラーコードはローカリゼーションの友です


4

+1データベース

データベースに修正が加えられた場合、アプリ内のフォームはその場で再翻訳することもできます。

すべてのコントロールがXMLファイル(フォームごとに1つ)で言語リソースIDにマップされているシステムを使用しましたが、すべてのIDはデータベースにありました。

基本的に、各コントロールにIDを保持させる(インターフェイスを実装する、またはVB6のtagプロパティを使用する)代わりに、.NETではコントロールツリーがリフレクションによって簡単に検出できるという事実を使用しました。フォームがロードされたときのプロセスは、XMLファイルが欠落している場合にそれを構築します。XMLファイルはコントロールをリソースIDにマップするため、これを入力してデータベースにマップするだけで済みます。これは、何かがタグ付けされていない場合、または別のIDに分割する必要がある場合(名詞と動詞の両方として使用される可能性のある英語の一部の単語を2つの異なる単語に翻訳する必要がある場合)、コンパイルされたバイナリを変更する必要がないことを意味しました辞書にあり、再利用されませんが、IDの最初の割り当て中にこれを発見できない場合があります)。

アプリがより関与するのは、挿入ポイントのあるフェーズが使用される場合だけです。

データベース翻訳ソフトウェアは、不足している翻訳などを簡単に処理するためのさまざまなワークフローオプションを備えた基本的なCRUDメンテナンス画面でした。


私はあなたの方法が好きです、xmlファイルがどのように生成されてデータベースにマッピングされるか教えていただけますか?
スミス

Form_Loadなどでは、変換関数がフォームインスタンスで呼び出されました。そのフォームのXMLファイルがロードされました。存在しなかった場合は作成されました。スキーマは手元にありませんが、基本的には、フォーム上のコントロール名を変換IDにマップしました。したがって、XMLファイルにないフォームのコントロールは、翻訳IDのないエントリを取得します。それらはオンデマンドで作成されるため、フォームを作成し、アプリを実行して、不足しているコントロールのXMLファイルをビルドまたは更新するだけで済みます。次に、アイテムの翻訳IDを入力します。
ケイドルー2018

4

私は検索していて、これを見つけました:

あなたは、WPFやSilverlightを使用している場合、あなたのaproachは、使用可能性がありWPF LocalizationExtension多くの理由のために。

ITのオープンソースそれは無料です(そして無料のままです)は本当のstabel状態です

Windowsアプリケーションでは、次のような操作を行うことができます。

public partial class App : Application  
{  
     public App()  
     {             
     }  
 
     protected override void OnStartup(StartupEventArgs e)  
     {  
         Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("de-DE"); ;  
         Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("de-DE"); ;  
 
          FrameworkElement.LanguageProperty.OverrideMetadata(  
              typeof(FrameworkElement),  
              new FrameworkPropertyMetadata(  
                  XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));  
          base.OnStartup(e);  
    }  
} 

そして、Wep Pageでは、アプローチは同じである可能性があると思います。

幸運を!


2

複数のリソースファイルを使用します。設定するのはそれほど難しいことではありません。実際、私は最近、フォーム言語のリソースファイルと組み合わせてグローバル言語ベースのリソースファイルを設定することに関する同様の質問に答えました。

Visual Studio2008でのローカリゼーション

少なくともWinForm開発には最善のアプローチだと思います。


リソースの欠点は、言語を切り替えるために再起動する必要があることです。それはおそらくほとんどの人にとって受け入れられますが、それは私のペット
のぞき見

2

Sisulizerのような市販のツールを使用できます。言語ごとに衛星アセンブリを作成します。注意が必要なのは、フォームクラス名を難読化しないことだけです(難読化ツールを使用している場合)。


0

ほとんどのオープンソースプロジェクトは、この目的のためにGetTextを使用しています。以前に.Netプロジェクトで使用されたことがあるかどうかはわかりません。


0

多言語サポート用のカスタムプロバイダーを使用し、すべてのテキストをデータベーステーブルに配置します。Webアプリケーションを更新せずにデータベース内のテキストを更新するときにキャッシュの問題に直面することがあることを除いて、これはうまく機能します。


0

標準のリソースファイルの方が簡単です。ただし、ルックアップテーブルなどの言語依存データがある場合は、2つのリソースセットを管理する必要があります。

私はそれをしていませんが、次のプロジェクトではデータベースリソースプロバイダーを実装します。私はMSDNでそれを行う方法を見つけました:

http://msdn.microsoft.com/en-us/library/aa905797.aspx

私もこの実装を見つけました:

DBResourceプロバイダー

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.