这必须发生在Silverlight客户端上:我们当然可以在开发机器上解析项目,但这会降低灵活性并在搜索中包含未使用的文件.
基本上我们希望能够在一个非常大的Prism项目中解析所有XAML文件(独立于加载它们)以识别所有本地化字符串.这将让我们构建一个初始本地化数据库,其中包括我们所有的资源绑定字符串,还可以创建查找它们所在的XAML文件(以便为翻译人员编辑).
为什么会这样?:翻译者最糟糕的事情就是在一个上下文中更改一个字符串,发现它在其他地方使用的含义略有不同.我们在应用程序本身内实现翻译的上下文编辑.
更新(9月14日):
由于安全限制,Silverlight无法使用标准迭代程序集的方法.这意味着下面解决方案的唯一改进是尽可能与Prism模块管理合作.如果有人想为此问题的最后一部分提供代码解决方案,可以与您分享一些分数!
跟进:
在基于模块的项目中迭代XAP文件的内容似乎是一个非常方便的事情,因为各种原因能够做到这一点,所以再添加100个代表来获得真正的答案(最好是工作示例代码).干杯,祝你好运!
下面的部分解决方案(工作但不是最佳):
下面是我提出的代码,它是从this link on Embedded resources(由Otaku建议)和我自己的Prism模块目录迭代的技术粘贴在一起.
>问题1 – 所有模块都是
已经加载所以这基本上是
必须全部下载它们
我无法解决的时间如何
迭代所有当前加载的Prism模块.
如果有人想分享赏金
在这一个,你仍然可以帮助
这个完整的解决方案!
>问题2 – 显然有一个错误
在需要的ResourceManager中
你得到一个已知的流
它之前的资源会让你
迭代所有资源项(请参阅下面代码中的注释).这意味着我必须在每个模块中都有一个虚拟资源文件.很高兴知道为什么需要初始的GetStream调用(或者如何避免它).
private void ParseAllXamlInAllModules() { IModuleCatalog mm = this.UnityContainer.Resolve<IModuleCatalog>(); foreach (var module in mm.Modules) { string xap = module.Ref; WebClient wc = new WebClient(); wc.OpenReadCompleted += (s,args) => { if (args.Error == null) { var resourceInfo = new StreamResourceInfo(args.Result,null); var file = new Uri("AppManifest.xaml",UriKind.Relative); var stream = System.Windows.Application.GetResourceStream(resourceInfo,file); XmlReader reader = XmlReader.Create(stream.Stream); var parts = new AssemblyPartCollection(); if (reader.Read()) { reader.ReadStartElement(); if (reader.ReadToNextSibling("Deployment.Parts")) { while (reader.ReadToFollowing("AssemblyPart")) { parts.Add(new AssemblyPart() { Source = reader.GetAttribute("Source") }); } } } foreach (var part in parts) { var info = new StreamResourceInfo(args.Result,null); Assembly assy = part.Load(System.Windows.Application.GetResourceStream(info,new Uri(part.source,UriKind.Relative)).Stream); // Get embedded resource names string[] resources = assy.GetManifestResourceNames(); foreach (var resource in resources) { if (!resource.Contains("DummyResource.xaml")) { // to get the actual values - create the table var table = new Dictionary<string,Stream>(); // All resources have “.resources” in the name – so remove it var rm = new ResourceManager(resource.Replace(".resources",String.Empty),assy); // Seems like some issue here,but without getting any real stream next statement doesn't work.... var dummy = rm.GetStream("DummyResource.xaml"); var rs = rm.GetResourceSet(Thread.CurrentThread.CurrentUICulture,false,true); IDictionaryEnumerator enumerator = rs.GetEnumerator(); while (enumerator.MoveNext()) { if (enumerator.Key.ToString().EndsWith(".xaml")) { table.Add(enumerator.Key.ToString(),enumerator.Value as Stream); } } foreach (var xaml in table) { TextReader xamlreader = new StreamReader(xaml.Value); string content = xamlreader.ReadToEnd(); { // This is where I do the actual work on the XAML content } } } } } } }; // Do the actual read to trigger the above callback code wc.OpenReadAsync(new Uri(xap,UriKind.RelativeOrAbsolute)); } }
解决方法
GetManifestResourceNames
反射并从那里解析只能得到以.xaml结尾的那些.下面是使用GetManifestResourceNames:
Enumerating embedded resources的示例.尽管示例显示了如何使用单独的.xap执行此操作,但您可以使用加载的.xap执行此操作.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。