创建表单实例时,XAML 解析器无法在动态加载的 XAP 中找到资源
我已经按照 Tim Heuer 的视频动态加载其他 XAP(进入“主”Silverlight 应用程序),以及一些其他链接来调整资源的加载,并且陷入了从动态加载的加载样式资源的特定问题上。 XAP(即Assets\Styles.xaml 的内容)。当我运行主/托管应用程序时,它成功地传输动态 XAP,我可以读取部署信息等并加载程序集部件。但是,当我实际尝试从动态 XAP 创建表单实例时,它失败了
找不到具有名称/键 LayoutRootGridStyle 的资源
,该资源位于其 Assets\Styles.xaml 文件中(如果我直接运行它,它就可以工作,所以我知道它没问题)。由于某种原因,这些没有显示为应用程序资源 - 不确定我是否完全搞错了,或者只是错过了一些东西?下面的代码片段(抱歉,它有点混乱 - 只是想先让它工作)...
'' # Here's the code that reads the dynamic XAP from the web server ...
'' #...
wCli = New WebClient
AddHandler wCli.OpenReadCompleted, AddressOf OpenXAPCompleted
wCli.OpenReadAsync(New Uri("MyTest.xap", UriKind.Relative))
'' #...
'' #Here's the sub that's called when openread is completed
'' #...
Private Sub OpenXAPCompleted(ByVal sender As Object, ByVal e As System.Net.OpenReadCompletedEventArgs)
Dim sManifest As String = New StreamReader(Application.GetResourceStream(New StreamResourceInfo(e.Result, Nothing), New Uri("AppManifest.xaml", UriKind.Relative)).Stream).ReadToEnd
Dim deploymentRoot As XElement = XDocument.Parse(sManifest).Root
Dim deploymentParts As List(Of XElement) = _
(From assemblyParts In deploymentRoot.Elements().Elements() Select assemblyParts).ToList()
Dim oAssembly As Assembly = Nothing
For Each xElement As XElement In deploymentParts
Dim asmPart As AssemblyPart = New AssemblyPart()
Dim source As String = xElement.Attribute("Source").Value
Dim sInfo As StreamResourceInfo = Application.GetResourceStream(New StreamResourceInfo(e.Result, "application/binary"), New Uri(source, UriKind.Relative))
If source = "MyTest.dll" Then
oAssembly = asmPart.Load(sInfo.Stream)
Else
asmPart.Load(sInfo.Stream)
End If
Next
Dim t As Type() = oAssembly.GetTypes()
Dim AppClass = (From parts In t Where parts.FullName.EndsWith(".App") Select parts).SingleOrDefault()
Dim mykeys As Array
If Not AppClass Is Nothing Then
Dim a As Application = DirectCast(oAssembly.CreateInstance(AppClass.FullName), Application)
For Each strKey As String In a.Resources.Keys
If Not Application.Current.Resources.Contains(strKey) Then
Application.Current.Resources.Add(strKey, a.Resources(strKey))
End If
Next
End If
Dim objectType As Type = oAssembly.GetType("MyTest.MainPage")
Dim ouiel = Activator.CreateInstance(objectType)
Dim myData As UIElement = DirectCast(ouiel, UIElement)
Me.splMain.Children.Add(myData)
Me.splMain.UpdateLayout()
End Sub
'' #...
'' # And here's the line that fails with "Cannot find a Resource with the Name/Key LayoutRootGridStyle"
'' # ...
System.Windows.Application.LoadComponent(Me, New System.Uri("/MyTest;component/MainPage.xaml", System.UriKind.Relative))
'' #...
回顾一下,有 3 种情况需要考虑... 1) 动态加载的 XAP 样式资源保留在合并的资源字典中(在单独的 xaml 文件中),从动态加载的 silverlight 应用程序 (XAP) 的 app.xaml 中引用 - 运行主应用程序时,来自动态 XAP 的资源似乎不存在于当前应用程序中(加载 XAP 程序集部件后)。发生错误。
2) 动态加载的 XAP 样式资源从合并的资源字典(从单独的 xaml 文件)移动到动态应用程序的 app.xaml 中,代替合并的资源字典引用。 - 运行主应用程序时,来自动态 XAP DO 的资源似乎出现在当前应用程序下(加载 XAP 组件部件之后)。但是,错误仍然发生。
3) 动态加载的XAP 样式资源被复制到调用/主应用程序的app.xaml 中(不可取)。 - 错误不再发生。
I've followed Tim Heuer's video for dynamically loading other XAP's (into a 'master' Silverlight application), as well as some other links to tweak the loading of resources and am stuck on the particular issue of loading style resources from within the dynamically loaded XAP (i.e. the contents of Assets\Styles.xaml). When I run the master/hosting applcation, it successfully streams the dynamic XAP and I can read the deployment info etc. and load the assembly parts. However, when I actuall try to create an instance of a form from the Dynamic XAP, it fails with
Cannot find a Resource with the Name/Key LayoutRootGridStyle
which is in it's Assets\Styles.xaml file (it works if I run it directly so I know it's OK). For some reason these don't show up as application resources - not sure if I've totally got the wrong end of the stick, or am just missing something? Code snippet below (apologies it's a bit messy - just trying to get it working first) ...
'' # Here's the code that reads the dynamic XAP from the web server ...
'' #...
wCli = New WebClient
AddHandler wCli.OpenReadCompleted, AddressOf OpenXAPCompleted
wCli.OpenReadAsync(New Uri("MyTest.xap", UriKind.Relative))
'' #...
'' #Here's the sub that's called when openread is completed
'' #...
Private Sub OpenXAPCompleted(ByVal sender As Object, ByVal e As System.Net.OpenReadCompletedEventArgs)
Dim sManifest As String = New StreamReader(Application.GetResourceStream(New StreamResourceInfo(e.Result, Nothing), New Uri("AppManifest.xaml", UriKind.Relative)).Stream).ReadToEnd
Dim deploymentRoot As XElement = XDocument.Parse(sManifest).Root
Dim deploymentParts As List(Of XElement) = _
(From assemblyParts In deploymentRoot.Elements().Elements() Select assemblyParts).ToList()
Dim oAssembly As Assembly = Nothing
For Each xElement As XElement In deploymentParts
Dim asmPart As AssemblyPart = New AssemblyPart()
Dim source As String = xElement.Attribute("Source").Value
Dim sInfo As StreamResourceInfo = Application.GetResourceStream(New StreamResourceInfo(e.Result, "application/binary"), New Uri(source, UriKind.Relative))
If source = "MyTest.dll" Then
oAssembly = asmPart.Load(sInfo.Stream)
Else
asmPart.Load(sInfo.Stream)
End If
Next
Dim t As Type() = oAssembly.GetTypes()
Dim AppClass = (From parts In t Where parts.FullName.EndsWith(".App") Select parts).SingleOrDefault()
Dim mykeys As Array
If Not AppClass Is Nothing Then
Dim a As Application = DirectCast(oAssembly.CreateInstance(AppClass.FullName), Application)
For Each strKey As String In a.Resources.Keys
If Not Application.Current.Resources.Contains(strKey) Then
Application.Current.Resources.Add(strKey, a.Resources(strKey))
End If
Next
End If
Dim objectType As Type = oAssembly.GetType("MyTest.MainPage")
Dim ouiel = Activator.CreateInstance(objectType)
Dim myData As UIElement = DirectCast(ouiel, UIElement)
Me.splMain.Children.Add(myData)
Me.splMain.UpdateLayout()
End Sub
'' #...
'' # And here's the line that fails with "Cannot find a Resource with the Name/Key LayoutRootGridStyle"
'' # ...
System.Windows.Application.LoadComponent(Me, New System.Uri("/MyTest;component/MainPage.xaml", System.UriKind.Relative))
'' #...
Just to re-cap, there are 3 scenarios to consider ...
1) The dynamically loaded XAP's style resources are left in a merged resource dictionary (in a seperate xaml file), referenced from the app.xaml of the dynamically loaded silverlight app (XAP) - When running the master application the resources from the dynamic XAP do not appear to be present under the current application (after loading the XAP assembly parts). Error occurs.
2) The dynamically loaded XAP's style resources are moved from the merged resource dictionary (from a seperate xaml file), into the app.xaml of the dynamic application, in place of the merged resource dictionary reference. - When running the master application the resources from the dynamic XAP DO appear to be present under the current application (after loading the XAP assembly parts). However, the error still occurs.
3) The dynamically loaded XAP's style resources are copied into the app.xaml of the calling/master application (not desirable). - Error no longer occurs.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
bykinag 在 silverlight 论坛 上提供的答案 ...
我添加了加载程序集后的以下行。
App.Current.Resources.MergedDictionaries.Add(New ResourceDictionary() With {.Source = New Uri("/MyTest;component/Assets/Styles.xaml", UriKind.RelativeOrAbsolute)})
我现在遇到一个问题,动态应用程序似乎看不到其中的其他页面(找不到页面),但如果我无法解决它,我可能会单独提出。
Answer provided by bykinag on silverlight forums ...
I added the following line after loading the assembly.
App.Current.Resources.MergedDictionaries.Add(New ResourceDictionary() With {.Source = New Uri("/MyTest;component/Assets/Styles.xaml", UriKind.RelativeOrAbsolute)})
I now have an issue where the dynamic application can't seem to see other pages within it (Page not found) but I'll probably raise that separately if I can't resolve it.