我有一个WinUI3类库,其中包含一个带有NavigationView的页面(MyFumulousPage.xaml),其中单击任何项目都会将框架导航到‘SamplePageA’.当我从WinUI未打包的应用程序中使用类库时,一切都按预期工作.

然而,当我试图从一个托管MyFabulousPage的WinForms应用程序中使用该库时,导航到SamplePageA会在WinRT深处的某个地方与AccessViolationException崩溃.

我try 按照this article中的建议添加app.manifest文件,但没有解决问题.

完整来源:https://github.com/nikolayvpavlov/Session_WindowsDesktop2024

推荐答案

对于一个XAML应用程序,可以有多个IXamlMetadataProvider个实例.默认情况下,所有这些都是由工具生成的,应用程序将所有XAML元数据解析推迟到提供者.

当您编写自己的定制应用程序时,系统仍会在运行时询问各种信息.在您的项目中,因为它是一个WinForms应用程序,所以工具不会自动公开与WinUI3项目对应的XAML元数据,所以当try 获取它时,应用程序会崩溃(UWP/WinUI3/XAML中的错误处理当前是very poor,这很糟糕...).

该XAML元数据提供程序驻留在您可以查看的文件XamlTypeInfo.g.cs中,并且通常位于Temp/Generated obj\Debug\net7.0-windows10.0.19041.0(版本可以改变)文件夹中.

下面是这个XamlTypeInfo.g.cs文件的样子:

namespace MyWinUILibrary.MyWinUILibrary_XamlTypeInfo
{
    /// <summary>
    /// Main class for providing metadata for the app or library
    /// </summary>
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.UI.Xaml.Markup.Compiler"," 3.0.0.2312")]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed class XamlMetaDataProvider : global::Microsoft.UI.Xaml.Markup.IXamlMetadataProvider
    {
        ...
    }

诀窍是您不能直接引用MyWinUILibrary.MyWinUILibrary_XamlTypeInfo.XamlMetaDataProvider类,因为存在鸡和蛋的问题(项目在生成文件之前不会编译,并且只有在项目编译时才会生成...).

所以你能做的就是在启动时通过反射加载它.以下是你的应用程序的一个修改后的版本,运行得更好:

public class DummyApp : Application, IXamlMetadataProvider
{
    private readonly XamlControlsXamlMetaDataProvider provider = new();
    private readonly IXamlMetadataProvider _myLibProvider;

    public DummyApp()
    {
        // find the generated IXamlMetadataProvider for this lib
        var type = GetType().Assembly.GetTypes()
            .FirstOrDefault(t =>
                typeof(IXamlMetadataProvider).IsAssignableFrom(t) &&
                t.GetCustomAttribute<GeneratedCodeAttribute>() != null);
        _myLibProvider = (IXamlMetadataProvider)Activator.CreateInstance(type);
    }

    public IXamlType GetXamlType(Type type)
    {
        var ret = provider.GetXamlType(type);
        ret ??= _myLibProvider.GetXamlType(type);
        return ret;
    }

    public IXamlType GetXamlType(string fullName)
    {
        var ret = provider.GetXamlType(fullName);
        ret ??= _myLibProvider.GetXamlType(fullName);
        return ret;
    }

    public XmlnsDefinition[] GetXmlnsDefinitions()
    {
        var ret = provider.GetXmlnsDefinitions();
        ret ??= _myLibProvider.GetXmlnsDefinitions();
        return ret;
    }

    protected override void OnLaunched(LaunchActivatedEventArgs args)
    {
        Resources.MergedDictionaries.Add(new XamlControlsResources());
        base.OnLaunched(args);
    }
}

Csharp相关问答推荐

ß != ss与ICU进行不区分大小写的比较

如何使用C#中的图形API更新用户配置文件图像

如何创建ASP.NET Core主机并在同一进程中运行请求

处理. netstandard2.0项目中HttpClient.SslProtocol的PlatformNotSupportedException问题""

Blazor Foreach仅渲染最后一种 colored颜色

(乌龙)1&#比c#中的UL&#慢吗?

尽管保证密钥不同,但已添加相同密钥的项(&Q;)

我如何让我的秒表保持运行场景而不重置

取决于您的数据量的多个嵌套循环

等待一个等待函数

当空判断结果赋给变量时,为什么会出现可能空异常警告的解引用?

为什么C#/MSBuild会自发地为不同的项目使用不同的输出路径?

解决方案:延长ABP框架和ANGING OpenIddict中的令牌生命周期

将J数组转换为列表,只保留一个嵌套的JToken

KeyDown从我的文本框中删除输入,如何停止?

.NET8支持Vector512,但为什么向量不能达到512位?

为什么我的UserControl没有加载到我的主窗口中?

我想我必须手动使用res1(字符串形式的PowerShell哈希表)

将两个JSON文件与覆盖值的主文件合并

MudRadioGroup不切换