我们需要创建我们的 WinForms 应用程序的 OEM 版本,该版本将具有一些与基本(en-US)版本不同的资源字符串(OEM 品牌)。这个应用程序已经针对中立的日本文化 (ja) 进行了本地化。
我正在尝试使用自定义文化来实现这一点,以我在这里找到的一篇文章为蓝本。我创造了两种文化:en-US-Acme 和 ja-Acme。这个想法是,对于 OEM 英语和日语版本,我们会在启动时适当地设置 CurrentUICulture。.Net 然后会自动提取正确的资源:首先查找 OEM 的资源文件(en-US-Acme 或 ja-Acme),如果未找到,则回退到默认资源文件(en-US 或 ja)。
我编写了一个小型的概念验证应用程序来尝试这一点,它非常适合特定的文化(en-US-Acme)。创建文化后,我可以设置表单的 Language 属性以使用它,Visual Studio 会创建相应的资源文件。在运行时,资源会按预期自动选择(带有回退)。
然而,中性文化 (ja-Acme) 存在一个问题:虽然可以创建自定义文化,但它不会在 Visual Studio 中显示为选项:
我的用于创建自定义文化的代码改编自上述文章,如下所示。尽管代码有效,但我并不完全确定我是否正确地创建了自定义中性文化。
所以两个问题:
- 这是创建自定义中立文化的正确方法吗?
- 为什么我的自定义中性文化没有出现在 Visual Studio 中?
我开始认为 Visual Studio 不支持自定义中性文化,我将不得不使用自定义特定文化 (ja-JP-Acme)。我还没有对此进行测试,但我认为回退(到 ja)仍然可以按我的需要工作。
var customCultures = CultureInfo.GetCultures( CultureTypes.UserCustomCulture );
if ( customCultures.Any( c => c.Name == "en-US-Acme" ) ) {
CultureAndRegionInfoBuilder.Unregister( "en-US-Acme" );
}
var builder = CultureAndRegionInfoBuilderHelper.CreateChildCultureAndRegionInfoBuilder( new CultureInfo( "en-US" ), "Acme", "(Acme)" );
builder.Register();
if ( customCultures.Any( c => c.Name == "ja-Acme" ) ) {
CultureAndRegionInfoBuilder.Unregister( "ja-Acme" );
}
builder = CultureAndRegionInfoBuilderHelper.CreateChildCultureAndRegionInfoBuilder( new CultureInfo( "ja" ), "Acme", "(Acme)" );
builder.Register();
//...
internal class CultureAndRegionInfoBuilderHelper {
public static CultureAndRegionInfoBuilder CreateChildCultureAndRegionInfoBuilder( CultureInfo parentCultureInfo, string childNameSuffix, string childDescriptiveSuffix ) {
var cultureName = parentCultureInfo.Name + "-" + childNameSuffix;
RegionInfo parentRegionInfo;
CultureAndRegionModifiers flags;
// Set region info and flags based on whether the parent culture is neutral or not.
if ( parentCultureInfo.IsNeutralCulture ) {
parentRegionInfo = null;
flags = CultureAndRegionModifiers.Neutral;
}
else {
parentRegionInfo = new RegionInfo( parentCultureInfo.Name );
flags = CultureAndRegionModifiers.None;
}
var builder = new CultureAndRegionInfoBuilder( cultureName, flags );
// load the culture and region data from the parent
builder.LoadDataFromCultureInfo( parentCultureInfo );
if ( parentRegionInfo != null ) {
builder.LoadDataFromRegionInfo( parentRegionInfo );
}
builder.Parent = parentCultureInfo;
var descriptiveSuffix = " " + childDescriptiveSuffix;
builder.CultureEnglishName += descriptiveSuffix;
builder.CultureNativeName += descriptiveSuffix;
if ( parentRegionInfo != null ) {
builder.RegionEnglishName += descriptiveSuffix;
builder.RegionNativeName += descriptiveSuffix;
}
return builder;
}
}