对于一个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);
}
}