The project exporter wrote every XAML document to the project root under
a fully-qualified name while the code-behind class went into a directory
named after its namespace, so the two halves of one partial class ended
up in different places. WPF tooling pairs MainWindow.xaml with
MainWindow.xaml.cs by name and location; anything else is an unrelated
file to it, and --nested-directories made the split wider still by moving
only the C# half.
Both now go through one function that decides where a type's files live,
so the document lands where the type's own C# file would have, and the
code-behind is named after the document. The BAML writers of the UI and
of the command line had grown their own copies of the naming, which is
how they came to disagree with the C# writer in the first place.
Assisted-by: Claude:claude-opus-5:Claude Code
The WPF markup compiler generates the program entry point from the
ApplicationDefinition item, so an exported project that lists App.xaml
as a Page has no Main at all and fails to build with CS5001. Both the
UI and ilspycmd already resolve the BAML root's partial class, which
makes deriving Application from System.Windows.Application the natural
signal. The module additionally has to have an entry point of its own:
a library that merely contains an Application subclass would otherwise
have MSBuild generate a Main into it.
Assisted-by: Claude:claude-opus-5[1m]:Claude Code
ResourceExtensions exposes the leaves of an assembly's embedded
resources — including individual entries inside .resources containers
— so callers can list and extract them by a stable path.
BamlAwareWholeProjectDecompiler subclasses WholeProjectDecompiler and
converts .baml entries to .xaml Page items, mirroring the pattern in
ILSpy.BamlDecompiler.BamlResourceFileHandler so PartialTypeInfo flows
through and the C# decompiler suppresses the duplicate Connect()
overrides.