How to instantiate a Page or User Control w/ NavigationView from a WinUI3 Class Library in WinForms Islands
See the question and my original answer on StackOverflowWhat's missing in the Winform's project hosting WinUI3 XAML islands is full XAML resolution, so NavigationView
and its dependencies are not fully available. This is easily solved in WinUI3 app as described here: Windows.UI.Xaml.Markup.XamlParseException on NavigationView
But by default you don't have a WinUI3 application since you're running a Winforms application. The solution is more or less (more less than more...) touched somehow in old UWP articles on XAML islands like Use XAML Islands to host a UWP XAML control in a C# WPF app but you still have to connect the bits.
So you must create a WinUI3 app and this app must implement the IXamlMetadataProvider Interface
implements XAML type resolution and provides the mapping between types used in markup and the corresponding classes implemented in an application or component.
Fortunately this is already implemented by the XamlControlsXamlMetaDataProvider Class (which is not documented, it would be too easy...) to which you can forward IXamlMetadataProvider
methods.
So, here is some sample code that you can use to start a WinUI3 app (aside the Winforms app, they can cohabit) capable of parsing what's needed here:
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Markup;
using Microsoft.UI.Xaml.XamlTypeInfo;
internal static class Program
{
[STAThread]
static void Main()
{
// add this here
// and BTW, this instance will become Microsoft.UI.Xaml.Application.Current
// which is null otherwise
_ = new MyApp();
ApplicationConfiguration.Initialize();
Application.Run(new MainForm());
}
}
public class MyApp : Microsoft.UI.Xaml.Application, IXamlMetadataProvider
{
private readonly XamlControlsXamlMetaDataProvider _provider = new();
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
{
// equivalent of this in an App.xaml file
//
// <Application ...
// <Application.Resources>
// <ResourceDictionary>
// <ResourceDictionary.MergedDictionaries>
// <XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
// </ResourceDictionary.MergedDictionaries>
// </ResourceDictionary>
// </Application.Resources>
// </Application>
//
Resources.MergedDictionaries.Add(new XamlControlsResources());
base.OnLaunched(args);
}
public IXamlType GetXamlType(Type type) => _provider.GetXamlType(type);
public IXamlType GetXamlType(string fullName) => _provider.GetXamlType(fullName);
public XmlnsDefinition[] GetXmlnsDefinitions() => _provider.GetXmlnsDefinitions();
}