Winforms 仅应用来自区域设置的本地化字符串(翻译)';s资源经理
我要求这是一个可能的解决办法。问题围绕着对表单中所有控件的Winforms 仅应用来自区域设置的本地化字符串(翻译)';s资源经理,winforms,localization,Winforms,Localization,我要求这是一个可能的解决办法。问题围绕着对表单中所有控件的ResourceManager.ApplyResources()的递归调用展开,这会导致所有锚定/布局重置为设计器中定义的大小(即ResourceManager中的默认值)。另一个问题试图通过在应用资源后尝试重新应用布局来解决问题,另一个问题是引导ApplyResources的行为,以便仅将本地化字符串应用于控件,而不是大小和位置属性,这些都是导致不良行为的原因 设计器通过将表单的Localizable属性设置为true,将表单的语言切换
ResourceManager.ApplyResources()
的递归调用展开,这会导致所有锚定/布局重置为设计器中定义的大小(即ResourceManager
中的默认值)。另一个问题试图通过在应用资源后尝试重新应用布局来解决问题,另一个问题是引导ApplyResources
的行为,以便仅将本地化字符串应用于控件,而不是大小和位置属性,这些都是导致不良行为的原因
设计器通过将表单的Localizable
属性设置为true
,将表单的语言切换为区域设置,并将控件的文本设置为该特定区域设置中的翻译,自动创建不同区域设置的资源文件
那么,不必使用ResourceManager.GetString()
逐个手动设置属性,这是否可行
提前谢谢 我能想到的一种方法是过滤资源管理器的内容 以下是封装在自定义扩展方法中的上述思想的实现:
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Resources;
namespace System.Windows.Forms
{
public static partial class Extensions
{
public static void ApplyResources(this Control target, Func<KeyValuePair<string, object>, bool> filter, CultureInfo culture = null)
{
ApplyResources(new FilteringComponentResourceManager(target.GetType(), filter), target, "$this", culture);
}
static void ApplyResources(FilteringComponentResourceManager resourceManager, Control target, string name, CultureInfo culture = null)
{
// Have the resource manager apply the resources to the given target
resourceManager.ApplyResources(target, name, culture);
// Iterate through the collection of children and recursively apply resources
foreach (Control child in target.Controls)
{
if (child is UserControl)
ApplyResources(child, resourceManager.Filter, culture);
else
ApplyResources(resourceManager, child, child.Name, culture);
}
}
class FilteringComponentResourceManager : ComponentResourceManager
{
ComponentResourceManager source;
Func<KeyValuePair<string, object>, bool> filter;
public FilteringComponentResourceManager(Type type, Func<KeyValuePair<string, object>, bool> filter)
{
this.source = new ComponentResourceManager(type);
this.filter = filter;
}
public Func<KeyValuePair<string, object>, bool> Filter { get { return filter; } }
protected override ResourceSet InternalGetResourceSet(CultureInfo culture, bool createIfNotExists, bool tryParents)
{
var sourceSet = source.GetResourceSet(culture, createIfNotExists, tryParents);
return sourceSet != null ? new FilteredResourceSet(sourceSet, filter) : null;
}
class FilteredResourceSet : ResourceSet
{
public FilteredResourceSet(ResourceSet source, Func<KeyValuePair<string, object>, bool> filter)
{
foreach (DictionaryEntry entry in source)
{
if (filter(new KeyValuePair<string, object>((string)entry.Key, entry.Value)))
Table.Add(entry.Key, entry.Value);
}
}
}
}
}
}
要仅应用字符串类型的属性
:
this.ApplyResources(entry => entry.Value is string);
this.ApplyResources(entry => entry.Value is string);