我看到的一些示例比它们需要的复杂得多,但这不是一项简单的任务。在我真正理解发生了什么之前,我花了 2 天时间分解我能找到的示例。
为此,您至少需要创建两个类。
一个实现 INavigationContentLoader 的类,它将完成所有工作。
实现 IAsyncResult 的类。该对象将传递 INavigationContentLoader,因此请使用它来跟踪您正在执行的操作。
您的 INavgiationContentLoader 应该执行以下操作。
开始加载
- 测试 Uri 是属于当前 XAP 还是属于已经加载的 XAP。
- 如果没有,请使用 DeploymentCatalog 下载 XAP。将 DeploymentCatalog 存储在 AggregateCatalog 中。
- 使用 ExportFactory 为给定的 Uri 创建页面。在 IAsyncResult 上给自己一个属性来保存它。
- 如果操作没有被取消,则执行回调参数。
可以加载
您可以尝试在此处放置一些逻辑来测试您是否可以访问指定的 XAP,或者您可以只返回 true 并完成它。
取消加载
在 IAsyncResult 中设置一个状态,让您知道操作已被取消。
结束加载
- 获取存储在 IAsyncResult 中的页面,将其包装在 LoadResult 中并返回。
将由此 INavgiationContentLoader 加载的所有页面都需要使用 ExportAttribute 进行标记,以便 ExportFactory 可以找到它们。
编辑
我的 INavigationContentLoader
http://pastebin.com/cT1mJ4Ve
我的 IAsyncResult
http://pastebin.com/xHWHT4pr
在页面上使用的ExportAttribute。您需要在所有页面上使用它,甚至是本地 XAP 中的页面。
http://pastebin.com/nTJ27mWz
IExportPageMetaData。这是 MEF 使用的合约。
http://pastebin.com/8fdwx2Kn
使用方法:
声明你的导航:像这样的框架
<navigation:Frame x:Name="ContentFrame"
Source="/Home"`
Grid.Column="1">
<navigation:Frame.ContentLoader>
<navUtil:DynamicContentLoader />
</navigation:Frame.ContentLoader>
</navigation:Frame>
HyperlinkButton 到另一个 XAP 的页面。
<HyperlinkButton Content="Page from another XAP"
NavigateUri="/NavigateUriFromExportPageAttribute"
navUtil:DynamicContentLoader.Xap="UriToOtherXap" />
HyperlinkButton 到此 XAP 中的页面。
<HyperlinkButton Content="Page from this XAP"
NavigateUri="/NavigateUriFromExportPageAttribute" />
您不需要 UriMapper,也不需要放置 Page.xaml 的路径。 MEF 将从页面中读取 ExportPageAttribute 并以这种方式找到 Uri。