2

DocumentViewerWPF 控制使用System.Windows.SR.Get(string)内部方法在搜索期间获取显示给用户的消息。即使我pl-PL设置为CurrentCultureand CurrentUICulture,这些都没有本地化。

我已经进行了一些调查,并从程序集中System.Windows.SR.Get(string)使用了这些消息,程序集又加载了带有这些消息的 ExceptionStringTable.resources 文件。据我了解,这是跨框架的标准本地化技术。new ResourceManager("ExceptionStringTable", typeof (System.Windows.SR).Assembly)PresentationFramework

我的问题是:如何让 WPF 显示我的自定义本地化消息?我尝试过使用 hacky 反射并且能够访问类内部ResourceManagerSR我应该将它包装在我的自定义ResourceManager实现中,还是有更简单的方法?

4

1 回答 1

2

我决定使用反射黑客。您必须在应用程序启动中使用此代码来交换ResourceDictionary内部 .NET 类中使用的代码SR

var assembly = typeof(DocumentViewer).Assembly;
var sr = assembly.GetType("System.Windows.SR");

var field = sr.GetField("_resourceManager", BindingFlags.NonPublic | BindingFlags.Static);


var resourceManager = (ResourceManager)field.GetValue(null);
var wrapper = new ResourceManagerWrapper(resourceManager);


wrapper.SetString("DocumentViewerSearchUpCompleteLabel", "test");
wrapper.SetString("DocumentViewerSearchDownCompleteLabel", "test");
wrapper.SetString("DocumentViewerSearchCompleteTitle", "test");
//And so on... you can find all those messages with dotPeek or similar tool in `DocumentViewer` implementation

field.SetValue(null, wrapper);

我将资源查找转发到 ResourceManager 的包装类非常简单:

public class ResourceManagerWrapper : ResourceManager
{
    private Dictionary<string, string> local_ = new Dictionary<string,string>();
    private ResourceManager manager_;
    public ResourceManagerWrapper(ResourceManager manager)
    {
        this.manager_ = manager;
    }

    public override string GetString(string name)
    {
        string value;
        if(local_.TryGetValue(name, out value))
        {
            return value;
        }
        else
        {
            return manager_.GetString(name);
        }
    }

    public void SetString(string key, string value)
    {
        local_[key] = value;
    }
}
于 2013-06-25T13:19:21.547 回答