DocumentViewer
WPF contorol正在使用System.Windows.SR.Get(string)
内部方法来显示向用户进行搜索时显示的消息。即使我将pl-PL
设置为CurrentCulture
和CurrentUICulture
,这些也不是本地化的。
我已经调查过一点System.Windows.SR.Get(string)
使用来自new ResourceManager("ExceptionStringTable", typeof (System.Windows.SR).Assembly)
程序集的PresentationFramework
,而ResourceManager
程序集又会使用这些消息加载ExceptionStringTable.resources文件。据我所知,这是整个框架的标准本地化技术。
我的问题是:如何让WPF显示我的自定义本地化消息?我尝试过使用hacky反射,并且能够访问SR
类的内部ResourceManager
。我应该将它包装在我的自定义{{1}}实现中,还是有更简单的方法?
答案 0 :(得分:1)
我决定参加反思黑客攻击。您必须在应用程序启动时使用此代码来交换内部.NET类ResourceDictionary
中使用的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;
}
}