【问题标题】:Show page from optional package in UWP在 UWP 中显示可选包中的页面
【发布时间】:2020-12-26 18:22:23
【问题描述】:

我想为我的 UWP 应用添加一些功能。可选包似乎是一种方法。 所以我把 ViewModel 类和 Page 类移到了可选包中,并把它们放到了可选包的命名空间中。 安装可选包后,我想显示移动的页面,但我总是收到以下错误:

Windows.UI.Xaml.Markup.XamlParseException
  HResult=0x802B000A
  Message=XAML parsing failed.
  Source=System.Private.Interop
  StackTrace:
   at System.Runtime.InteropServices.McgMarshal.ThrowOnExternalCallFailed(Int32 hr, RuntimeTypeHandle typeHnd) in f:\dd\ndp\fxcore\CoreRT\src\System.Private.Interop\src\Shared\McgMarshal.cs:line 1189
   at __Interop.ComCallHelpers.Call(__ComObject __this, RuntimeTypeHandle __typeHnd, Int32 __targetIndex, Void* arg0, Void* arg1, Int32 arg2)
   at Windows.UI.Xaml.IApplicationStatics__Impl.Stubs.LoadComponent(__ComObject __this, Object component, Uri resourceLocator, ComponentResourceLocation componentResourceLocation)
   at Windows.UI.Xaml.Application.__Factory_Windows_UI_Xaml__IApplicationStatics_LoadComponent(String typeName, Object component, Uri resourceLocator, ComponentResourceLocation componentResourceLocation)
   at Windows.UI.Xaml.Application.LoadComponent(Object component, Uri resourceLocator, ComponentResourceLocation componentResourceLocation)
   at <my classes>

如何加载和显示可选包的页面?

【问题讨论】:

  • 您好,从错误信息来看,问题可能来自您移动的页面的 XAML 部分。你能提供一个最小的复制样本,以便我们分析这个问题吗?
  • 您好@RichardZhang-MSFT,感谢您的回答。我将创建一个包含最少项目的解决方案,并在下面的评论中添加一个链接。
  • @RichardZhang-MSFT 我在github.com/pinki/ShowPageOfOptionalPackageErrorSample创建了一个项目

标签: uwp


【解决方案1】:

终于发现,生成的InitializeComponent()方法不对。

在我的sample code repositoryfixed 分支中是一个可行的解决方案。

在可选包的Pages后面的代码中,构造函数对InitializeComponent()的调用必须替换为以下代码:

Uri resourceLocator = new Uri("ms-appx://ad4d8e16-9f9c-458f-ac0f-e74cb99fa10c/HalloPage.xaml");
Application.LoadComponent(this, resourceLocator, ComponentResourceLocation.Nested);

ad4d8e16-9f9c-458f-ac0f-e74cb99fa10c 是可选包的身份名称。如果您想加载图像、资源字典等,您必须以相同的格式编写 URI,包括可选包的身份名称。否则,您将从主应用程序加载资源。

如果工具链能够自己生成正确的 URI,那就太好了。

【讨论】:

    【解决方案2】:

    我检查了你的项目,你在MainApp项目中添加了可选包项目引用,这不是可选包的推荐开发方式。

    可选包是附加的,就像游戏的DLC一样,不会影响主应用,也不是主应用项目的必要参考。

    这意味着MainApp项目和可选包项目需要分开安装。事实上,你不能在一个 UWP 应用项目中引用另一个 UWP 应用项目,它们的入口点是冲突的。

    所以请按照以下步骤操作:

    1. 删除MainApp项目中对可选包项目的引用。
    2. 恢复可选包项目中的App.xamlMainPage.xaml 文件。 (可以新建一个 UWP 应用项目,可能会更简单)
    3. 修改可选包项目中Package.appxmanifest的内容,如this blog中所述,去掉Capability标签,添加对MainPackageDependency的引用。

    从这些步骤可以发现,HalloPage 类在 MainApp 项目中不能再被直接引用。同时,即使安装了可选包,也无法通过反射获取页面类型。

    因此将页面放在可选包中可能不是一个合适的解决方案。

    【讨论】:

    • 感谢您检查我的项目。可选包的项目中从来没有 App.xaml。我按照这些说明 (docs.microsoft.com/en-us/windows/msix/package/…) 说明我必须引用可选包的 .winmd 文件才能调用可选包的代码。我现在有点困惑。
    • 如果我只使用 C# 代码构建页面,我可以创建该页面的对象并将其设置为 Frame 的内容(使用 NavigateTo 不起作用),但我无法获得它适用于 XAML 页面。
    • 对不起,我错过了一些东西。在document 中,您需要引用的是winmd 文件,该文件包含类型定义,这是您访问MainApp 中可选包中的类型的基础。在 Bundle.mapping.txt 文件中,需要引用 winmd 文件而不是 csproj 文件。但是,在我的测试中,引用 winmd 文件导致另一个加载错误。我会报告这个问题,如果有新信息我会在这里发布
    • 我终于找到了一种从可选包中加载 xaml 页面的方法。有没有办法让工具链为我做修复?
    • 您好,很高兴您找到了解决方案。您可以标记您的答案,以便帮助更多有相同问题的人。关于这个变通方法,这似乎是一个内部资源管理设置,您可以在 Windows10 反馈中心应用程序中提出这个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-22
    • 2018-12-21
    相关资源
    最近更新 更多