Hi @Hong ,
The Dummy page can work around missing XAML type metadata, but a converter does not normally require a dummy page. I reproduced the same type-not-found error in a small WinUI 3 project by including the dictionary as loose XAML (Content) rather than compiled XAML (Page). Adding your dummy-page pattern removed that error without ever creating or navigating to the page. This is one reproducible explanation for your observation, not yet confirmation of your project's configuration.
Microsoft's XAML resources documentation explicitly supports custom types such as IValueConverter implementations as shared resources. It requires a default constructor for XAML instantiation and excludes types derived from UIElement. The converter you posted has an implicit public parameterless constructor, so it fits that resource pattern; XAML still needs to be able to resolve its type.
The distinction is between having the converter class in the assembly and making it available to XAML type resolution. The XAML compiler generates IXamlMetadataProvider implementations, which map types used in markup to their implementations. Microsoft's IXamlMetadataProvider documentation and IXamlType remarks describe that mechanism and the generated XamlTypeInfo.* files.
The XAML resources documentation also notes that some resource-lookup parse errors are detected only at runtime, not during compilation or in the designer. That passage is about resource lookup rather than this specific missing-type error. In the sample here, the build also succeeded and the type-resolution error appeared only when the app started, so a successful build alone does not rule it out.
In the failing sample, the library had no compiled XAML and no generated provider for the converter. Compiling Dummy.xaml, which references the converter, caused that metadata to be generated and included in the app's provider chain. That is why the page's presence in the build mattered even though the page was never opened. Simply adding an unused page is not what fixes it; the relevant change is the generated metadata.
For your project, first check the resource dictionary's Build Action in Visual Studio and the library's .csproj. If this is intended to be a compiled library dictionary, it should be included as Page, rather than only Content or None. Check for conditional item entries or a Page Remove that excludes the file from XAML compilation. The file may already be included through default project items, so do not add a duplicate Page Include. Page is the build item name here; the XAML root remains ResourceDictionary. In my test, the following dictionary worked without x:Class, code-behind, or a dummy page:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:common="using:ClassLibraryWinUI.Common">
<common:NullableBooleanToBooleanConverter
x:Key="NullableBooleanToBooleanConverter" />
</ResourceDictionary>
For that sample, the file was Converters.xaml at the root of the ClassLibraryWinUI project, and the app referenced that project. The entry inside the app's ResourceDictionary.MergedDictionaries was:
<ResourceDictionary
Source="ms-appx:///ClassLibraryWinUI/Converters.xaml" />
Use the path corresponding to your actual library and dictionary location. The XAML resources documentation explains the Source/MergedDictionaries pattern. Also check that the app's .csproj references the intended library project or package.
If the dictionary is already compiled as Page, compare fresh builds with and without Dummy.xaml. Search the library's generated obj\...\XamlTypeInfo.g.cs for the fully qualified converter name and its activation code. Then check whether the app's generated OtherProviders includes the library's XamlMetaDataProvider. If either disappears when the dummy page is removed, that narrows the issue to metadata generation or provider discovery. Inspect these generated files rather than editing them, since rebuilding replaces them.
For reference, I ran the sample on Windows App SDK 1.7.250909003, .NET 8, x64, Debug, unpackaged. The image compares four configurations using the actual results and runtime logs from that sample, not your application. The loose-XAML configuration reproduces the reported error; the compiled dictionary works without Dummy.
The key error from the loose-XAML run is also available as text:
The type 'NullableBooleanToBooleanConverter' was not found. [Line: 8 Position: 37]
The sample reports line 8 rather than line 13 because its XAML file has a different layout. The error names the same converter type; the different line number does not by itself indicate a different error, nor does the matching message establish the cause in your project.
The compiled dictionary run also recorded this binding result:
CheckBox.IsChecked=True; observed targetType=System.Boolean
The binding observation is also relevant to your targetType check: an actual one-way binding to CheckBox.IsChecked passed typeof(bool) in this test. I would not change that check to typeof(bool?) as a fix for the startup error. Its exception message says “nullable boolean,” which does not match the check, but that wording is separate from the type-resolution failure.
Could you share which XAML file the reported line 13 belongs to, the dictionary's build action and location, the XAML that merges it, and the Windows App SDK version used by the app and library? Please include any relevant dictionary item or library-reference entries from the .csproj files. Those details will help distinguish the loose-XAML case demonstrated here from a metadata issue in an already compiled dictionary. You can keep the working dummy page while checking this; there is no need to remove your workaround permanently before an alternative is verified.
Thank you.