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);