UWP多语言场景下运行时修改已加载Resx资源字符串相关问题问询
UWP多语言资源加载与运行时修改解答
1. 多语言资源的加载承载类
UWP中基于Resx、Xliff的多语言资源,运行时会加载到两类核心对象中:
- 自动生成的强类型资源类:添加Resx文件后Visual Studio会自动生成同名静态类(例如
Strings.resx对应生成Strings静态类),所有资源项以静态属性的形式暴露,资源内容编译后作为程序集的嵌入资源,运行时加载后缓存在该类的静态字段中,日常开发中直接写Strings.xxx获取资源就是调用的这个类。 - 系统级资源加载对象:系统提供的
Windows.ApplicationModel.Resources.ResourceLoader类是通用资源获取入口,ResourceLoader.GetForCurrentView()返回的实例会加载当前ResourceContext(包含语言、缩放系数等上下文参数)匹配的资源,资源内容会缓存在ResourceContext对应的内存空间中,手动设置Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride后系统会自动更新ResourceContext和对应的资源缓存。
2. 能否直接修改内存中已加载的Resx资源
不可以。
Resx文件在编译阶段会被处理为程序集的不可变嵌入资源,运行时加载到上述两类对象的缓存都是只读的,没有公开的修改接口。即便通过反射强制修改缓存值,也无法触发UI层已绑定资源的自动更新,且存在版本兼容风险,完全不推荐这么做。
3. 运行时修改多语言内容的可行替代方案
以下三种方案都可以满足运行时修改资源值、UI自动生效的需求:
- 自定义多语言管理类:完全绕开默认Resx绑定,实现一个实现
INotifyPropertyChanged接口的单例资源管理类,启动时将所有Resx资源读取到可写的Dictionary<string, string>缓存中,所有UI的多语言绑定都指向该单例的索引器属性。修改指定资源ID的内容后,触发索引器的属性变更通知,所有绑定该ID的UI会自动更新为新值。
核心逻辑示例:public class CustomResourceManager : INotifyPropertyChanged { public static CustomResourceManager Instance { get; } = new(); private readonly Dictionary<string, string> _resourceCache = new(); public string this[string resourceKey] { get => _resourceCache.TryGetValue(resourceKey, out var value) ? value : resourceKey; set { _resourceCache[resourceKey] = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(Binding.IndexerName)); } } // 初始化加载Resx资源到_cache的逻辑省略 public event PropertyChangedEventHandler PropertyChanged; } - 混合覆写方案:保留默认Resx的基础多语言能力,在自定义资源管理类中额外增加一个覆写字典,获取资源时优先返回覆写字典的内容,不存在时再调用默认
ResourceLoader取Resx中的值。修改资源时只需要更新覆写字典的对应值即可,不需要修改原有Resx相关逻辑。 - 外部资源文件方案:将需要动态修改的多语言资源单独存放在应用本地存储目录的Json/Xml文件中,运行时优先加载本地目录的资源,打包内置的Resx仅作为兜底。该方案不仅支持运行时修改,还可以实现多语言资源的在线更新,不需要重新发布应用版本。
内容的提问来源于stack exchange,提问作者Neha
相关产品推荐
相关产品推荐

