Skip to content

WinUI templates for dotnet new and VSIX - #6407

Merged
Dinah Xiaoman G (DinahK-2SO) merged 53 commits into
mainfrom
user/muyuanli/dotnetnewtemplate
May 18, 2026
Merged

WinUI templates for dotnet new and VSIX#6407
Dinah Xiaoman G (DinahK-2SO) merged 53 commits into
mainfrom
user/muyuanli/dotnetnewtemplate

Conversation

@DinahK-2SO

@DinahK-2SO Dinah Xiaoman G (DinahK-2SO) commented Apr 16, 2026

Copy link
Copy Markdown
Contributor

This PR adds/updates the WinUI App templates:

  1. Add WinUI templates for dotnet new
  2. Add 3 new templates for Visual Studio:
    • WinUI Navigation App
    • WinUI TabView App
    • WinUI MVVM App
  3. Add guidelines and scripts for local build
image

@DinahK-2SO
Dinah Xiaoman G (DinahK-2SO) marked this pull request as ready for review April 17, 2026 07:32
@DinahK-2SO Dinah Xiaoman G (DinahK-2SO) changed the title User/muyuanli/dotnetnewtemplate WinUI dotnet new templates Apr 17, 2026
@DinahK-2SO Dinah Xiaoman G (DinahK-2SO) changed the title WinUI dotnet new templates WinUI templates for dotnet new and VSIX Apr 17, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

@DinahK-2SO
Dinah Xiaoman G (DinahK-2SO) force-pushed the user/muyuanli/dotnetnewtemplate branch from 75d7c86 to e3fc78f Compare April 20, 2026 03:33
Muyuan Li (MuyuanMS) and others added 20 commits April 20, 2026 16:02
* Add pipelines
* Update readme
* Adding TitleBar and .ico

* Adding the ContentDialog ItemTemplate

* Adding NavigationView template

* Missed a csharp template and added

* Push

* Update WinAppSdk.CSharp.DotnetNewTemplates.csproj

* Clean up navview project

* Update dev/VSIX/ProjectTemplates/Desktop/CSharp/NavigationApp/Pages/HomePage.xaml.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update dev/VSIX/ProjectTemplates/Desktop/CSharp/NavigationApp/Pages/AboutPage.xaml.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update dev/VSIX/ProjectTemplates/Desktop/CSharp/NavigationApp/Pages/SettingsPage.xaml.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update dev/VSIX/ProjectTemplates/Desktop/CSharp/NavigationApp/App.xaml.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update dev/VSIX/ItemTemplates/Neutral/CSharp/ContentDialog/ContentDialog.xaml.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update dev/VSIX/ProjectTemplates/Desktop/CSharp/NavigationApp/MainWindow.xaml.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Add default case with exception to navigation switch statement (#6252)

* Initial plan

* Add default case throwing InvalidOperationException in navigation switch statement

Co-authored-by: niels9001 <9866362+niels9001@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: niels9001 <9866362+niels9001@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: niels9001 <9866362+niels9001@users.noreply.github.com>
* Add missing item-content-dialog template for dotnet new

The csproj referenced templates/item-content-dialog/ but the directory
did not exist, which would cause dotnet pack to produce an incomplete
package. Create the template.json, dotnetcli.host.json, and the XAML
and code-behind files for a WinUI 3 ContentDialog item template.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add packaged template to NuGet template pack

The templates/packaged/ directory existed with a full template.json and
solution file but was never included in the csproj ItemGroups, so it
would not ship in the NuGet package. Add the ItemGroup that packs the
template config, solution, BlankApp, and WapProj sources.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Update README with packaged and content-dialog templates

The template table was missing the wasdk-packaged and wasdk-item-dialog
entries. Add both so the README accurately documents all templates
shipped in the pack.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add language and type tags to all template.json files

Without the 'tags' property, 'dotnet new list' does not show the
language column and template discoverability is reduced. Add
tags.language=C# and tags.type (project, solution, or item) to every
template.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add postActions for automatic NuGet restore

After 'dotnet new' creates a project, the user currently has to
manually run 'dotnet restore'. Add the standard NuGet restore post-
action (actionId 210D431B) to the four project templates so packages
are restored automatically. Item templates do not need this.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add Windows-only OS constraint to all templates

WinUI 3 / Windows App SDK templates only work on Windows. Without the
constraint, 'dotnet new list' shows them on Linux and macOS where they
cannot build, leading to confusing errors. Add the os constraint so
the templates are hidden on non-Windows hosts.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add description fields to template parameters

The single-project, class-library, and unit-test templates were missing
description fields on their user-facing parameters. The packaged
template already had them. Add matching descriptions so 'dotnet new
<template> --help' displays useful parameter documentation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add description fields to dotnetcli.host.json files

The packaged template's host file already had descriptions but the
single-project, class-library, unit-test, and item-blank-window host
files did not. Add descriptions so 'dotnet new <template> --help'
displays useful help text for every parameter.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add Copyright, license acceptance, and release notes to csproj

The NuGet package was missing Copyright, PackageRequireLicenseAcceptance,
and PackageReleaseNotes metadata. Add them for completeness and better
presentation on NuGet feeds.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Update default dotnetVersion from net8.0 to net9.0

.NET 9.0 is the current release. Update the default TFM across all
four project templates and their dotnetcli.host.json description
examples. Users can still override with --dotnet-version net8.0.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Use https:// for JSON schema URLs

All template.json and dotnetcli.host.json files used http:// for the
schema store URLs. Update to https:// for consistency and security.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Revert packaged template from dotnet new pack

The wasdk-packaged template uses a WAP project (.wapproj) which the
dotnet CLI does not understand, so it cannot be used with 'dotnet new'.
Remove the packaged template ItemGroup from the csproj, remove it from
the README, and restore its template.json and dotnetcli.host.json to
their pre-modification state.

This reverts the packaged-related portions of commits 31f65f2,
b8c76b7, 80c1b8f, 63d5abf, ff0bc38, 7c03a19, and 4891155.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Use existing VS ContentDialog sources instead of hand-crafted copies

The ContentDialog XAML and code-behind already exist at
ItemTemplates/Neutral/CSharp/ContentDialog/. Link those files in the
csproj instead of maintaining separate copies, matching the pattern
used by the BlankWindow item template. This keeps a single source of
truth and preserves the original button click handlers.

Also update template.json sourceName and primaryOutputs to match the
original filenames (ContentDialog, not ContentDialogItem), and remove
the now-unnecessary Compile Remove directive.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Align packaged template config with other templates

The previous revert restored the packaged template.json and
dotnetcli.host.json to their original state, making them inconsistent
with the rest of the templates. Re-apply the same improvements: add
tags, constraints, postActions, update schema to https://, and default
TFM to net9.0.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Remove templates/packaged/ directory

The packaged template uses a WAP project (.wapproj) which the dotnet
CLI does not support, so it is not included in the NuGet template pack.
Remove the unused directory to avoid confusion.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Update default dotnetVersion from net9.0 to net10.0

.NET 10.0 is the latest officially supported version. Update the
default TFM and help text examples across all project templates.
Users can still override with --dotnet-version net8.0 or net9.0.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Rename template shortNames from wasdk-* to winui3-*

Use winui3- prefix instead of wasdk- since WinUI 3 is the product
name users recognize, not the shipping vehicle (Windows App SDK).

  wasdk-single        -> winui3
  wasdk-classlib      -> winui3-lib
  wasdk-unittest      -> winui3-unittest
  wasdk-item-blankwin -> winui3-window
  wasdk-item-dialog   -> winui3-dialog

Also update display names and default project names to match.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add winui3-page and winui3-usercontrol item templates

Add two new item templates that link existing VS template sources from
ItemTemplates/Neutral/CSharp/:

  winui3-page        - BlankPage (Page with XAML and code-behind)
  winui3-usercontrol - UserControl (UserControl with XAML and code-behind)

Both follow the same pattern as winui3-window and winui3-dialog: the
template.config is maintained locally while XAML/code-behind are linked
from the shared VS template sources.

Note: the dotnet new template engine does not support verifying that an
existing project exists before adding an item template. The
msbuild:RootNamespace binding will fall back to the default value if no
project is found.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add project-capability and sdk-version constraints to item templates

Item templates (window, page, usercontrol, dialog) should only appear
in 'dotnet new list' when run inside a C# project folder. Add a
'project-capability' constraint with 'CSharp' so the templates are
hidden when no C# project is found in the current directory. Also add
an sdk-version constraint requiring .NET 8.0 or later.

Inspired by https://github.com/egvijayanand/winui-templates which uses
the same approach.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add sdk-version constraint to project templates

Require .NET 8.0 SDK or later for the three project templates
(single-project, class-library, unit-test). The templates target
net10.0-windows and will not work on older SDKs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* chore(project): update NoWarn property to include CS2008 warning

* feat(templates): update template identities to use WinUI naming convention

* feat(templates): add symbols section to various template configurations

* feat(templates): update dotnetVersion to support .NET 8, 9, and 10 choices

* template renamings

* User/muyuanli/naming improvements (#6256)

* template renamings

* Update naming and schema

* Add back agents and instructions

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Muyuan Li (from Dev Box) <muyuanli@microsoft.com>
Co-authored-by: Muyuan Li <116717757+MuyuanMS@users.noreply.github.com>
* Enhance copilot instructions and project spec

* Fix indentation
* complete nuspec

* Update dev/VSIX/DotnetNewTemplates/WinAppSdk.CSharp.DotnetNewTemplates.csproj

Co-authored-by: Niels Laute <niels.laute@live.nl>

* Update dev/VSIX/DotnetNewTemplates/WinAppSdk.CSharp.DotnetNewTemplates.csproj

Co-authored-by: Niels Laute <niels.laute@live.nl>

* Update dev/VSIX/DotnetNewTemplates/README.md

Co-authored-by: Niels Laute <niels.laute@live.nl>

* Resolve comments

---------

Co-authored-by: Niels Laute <niels.laute@live.nl>
* Update default dotnet version to be 10.0

* Update vstemplate to be dotnet 10 as well
* set dotnet version based on installed sdk version, and increase windows sdk in tfm

* Add test script and fix existing issues with item templates

---------

Co-authored-by: Nikola Metulev <nmetulev@users.noreply.github.com>
* added frame and mainpage to main window

* winui template updates

* adding mvvm template

---------

Co-authored-by: Nikola Metulev <711864+nmetulev@users.noreply.github.com>
* Remove invalid classifications and add missing XAML

The classications now match the classifications from the VSIX templates

* Ensures IDE shows the correct field information

Also makes min version a dropdown, and sets default based on current support lifecycles / recommendations.

* Add missing min versions
)

* Updated icons

* Remove assets folder (it already pulls those from the other template)

* Layout tweaks to the navview template

* Adding a TabView template

* Update the MvvM template with counters

* Design tweaks for the TabView template

* Update icon.png
@DinahK-2SO

Copy link
Copy Markdown
Contributor Author

To reviewers, I found there were 2 orphan item templates in Dotnet files:

  • dev/Templates/Dotnet/templates/item-page/
  • dev/Templates/Dotnet/templates/item-usercontrol/

which were duplicates of the items actually included in the package:

  • dev/Templates/Dotnet/templates/item-blank-page
  • dev/Templates/Dotnet/templates/item-user-control

The orphans were never referenced by templates.props and never made it into the generated .nuspec. They had also been silently broken since day one. So I removed them in the last iteration.

…om blank-app template (they will be re-organised in a follow-up PR)
@DinahK-2SO
Dinah Xiaoman G (DinahK-2SO) force-pushed the user/muyuanli/dotnetnewtemplate branch from ecca4da to 5881332 Compare May 15, 2026 05:19
@DinahK-2SO

Copy link
Copy Markdown
Contributor Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@DinahK-2SO
Dinah Xiaoman G (DinahK-2SO) enabled auto-merge (squash) May 15, 2026 17:53
@DinahK-2SO

Copy link
Copy Markdown
Contributor Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@DinahK-2SO
Dinah Xiaoman G (DinahK-2SO) merged commit 9b5d40a into main May 18, 2026
50 checks passed
@DinahK-2SO
Dinah Xiaoman G (DinahK-2SO) deleted the user/muyuanli/dotnetnewtemplate branch May 18, 2026 05:38
Alexandre Zollinger Chohfi (azchohfi) added a commit that referenced this pull request Jul 30, 2026
The root .gitignore has a blanket `*.pubxml` rule, so the three publish
profiles in each Reactor template were silently never added. They existed
only on the authoring machine; a clean clone got none of them. The WinUI
templates force-added theirs in #6407 for the same reason.

Without the profiles the csproj's
`<PublishProfile Condition="Exists(...)">` never resolves, so SelfContained
is never set to true. Combined with PublishTrimmed=true for non-Debug
configurations that fails a Release build outright:

  error NETSDK1102: Optimizing assemblies for size is not supported for the
  selected publish configuration. Please ensure that you are publishing a
  self-contained app.

Force-add all 12 files so Release builds and publish work from a fresh
clone, matching the WinUI templates.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 16d7d2fc-3d7c-41e8-9999-0c2084ba9ea1
Alexandre Zollinger Chohfi (azchohfi) added a commit that referenced this pull request Aug 28, 2026
* Add Reactor (Microsoft.UI.Reactor) dotnet new templates

Adds four Reactor project templates to the Microsoft.WindowsAppSDK.WinUI.CSharp.Templates dotnet-new pack, mirroring the WinUI templates but for Microsoft.UI.Reactor (pure C#, no XAML):

- Reactor Blank App        (reactor, reactor-blank)
- Reactor MVU App          (reactor-mvu)
- Reactor NavigationView   (reactor-navview)
- Reactor TabView App      (reactor-tabview)

Wired into dev/Templates/templates.props via the DotnetNewOnlyProjectTemplate
slot (dotnet-new only, no VSIX, no manifest; Reactor apps run unpackaged).
Each shares a common csproj referencing Microsoft.UI.Reactor +
Microsoft.WindowsAppSDK, bundles the WinAppSDK runtime self-contained, and
enables the Debug-only Reactor devtools surface. README and
Test-DotnetNewTemplates.ps1 updated to document and validate the new templates.

Validated end-to-end: pack -> install -> dotnet new -> build (Debug + Release)
for all four templates.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* Fix Reactor template runtime crash: remove TitleBar icon

TitleBar(...).Icon(FontIcon(...)) threw System.ArgumentException (E_INVALIDARG)
at runtime when Reactor set TitleBar.IconSource on Windows App SDK 2.1.3, so
the scaffolded Blank, MVU, and TabView apps crashed on launch. The glyph was
only a placeholder, so drop the icon; the title bar still shows the title text
and all four templates now launch cleanly (validated with dotnet run).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* Bump Reactor templates to preview.12 and restore title-bar icon

microsoft/microsoft-ui-reactor#855 fixes the IconResolver FontSize=NaN crash
(FontIcon in an IconSource slot without an explicit size threw
ArgumentException from TitleBar.set_IconSource). That fix ships in
Microsoft.UI.Reactor 0.1.0-preview.12, so restore the placeholder title-bar
app-mark icon in the Blank, MVU, and TabView templates and bump the default
reactorVersion 0.1.0-preview.11 -> 0.1.0-preview.12 across all four templates.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* Provision .NET 10 SDK in dotnet-new templates test stage

The template smoke-test stage installed only .NET SDK 8.0.x, so scaffolding
and building the Reactor templates failed with NETSDK1045 (Reactor targets
net10.0 and declares a [10.0,) sdk-version constraint). The WinUI templates
auto-detect their TFM from the active SDK, so they built net8.0 and passed,
masking the gap.

Add a second UseDotNet@2 step (param reactorDotnetSdkVersion, default 10.0.x)
to the shared Test-Stage template so the agent has the .NET 10 SDK. Verified
locally that the WinUI templates still build cleanly on the .NET 10 SDK, so
existing coverage is unaffected. Both the official and PR pipelines consume
this shared stage.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* Address PR review: trim launchSettings comments, use per-template icons

Review feedback from @DinahK-2SO on #6620:
- Remove the explanatory comment block from the Reactor launchSettings.json
  files (the content overlapped the package README).
- Give the MVU, NavigationView, and TabView templates their own icon.png
  (reusing the existing WinUI mvvm/navigation/tabview template icons) instead
  of all reusing the blank-app icon.

The packaging/taskbar-icon, tabs-in-title-bar, and winui-* short-name comments
are still open pending a check with the Reactor team.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* Add winui-reactor* short-name aliases to Reactor templates

Review feedback from @DinahK-2SO on #6620: give each Reactor template a
winui-reactor* alias (winui-reactor, winui-reactor-mvu, winui-reactor-navview,
winui-reactor-tabview) so they also surface under 'dotnet new list winui'
alongside the other WinUI templates. README updated to note the aliases.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* reactor-tabview: integrate tabs into the title bar

Review feedback from @DinahK-2SO on #6620: instead of stacking a separate
TitleBar row above the TabView, put the tabs up in the title bar (Edge/Terminal
style) to look cleaner and save vertical space.

Uses supported Reactor APIs: UseWindow().NativeWindow with
ExtendsContentIntoTitleBar + SetTitleBar, the TabView TabStripHeader (app name
at the leading edge) and TabStripFooter (draggable region), and UseDpi +
UseWindowSize to reserve the caption-button inset (RightInset) across DPI and
resize. Verified by scaffolding the template, building, running, and
screenshotting the window: the tabs render inline in the title bar with the
caption buttons clear.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* Make Reactor templates packaged (MSIX) and match the WinUI templates

Per review direction, the four Reactor templates now:

1. Are single-project MSIX packaged (like the WinUI templates) instead of
   unpackaged. Each gains app.manifest, Package.appxmanifest (EntryPoint
   Windows.FullTrustApplication since Reactor has no XAML App class), the shared
   Assets, and PublishProfiles. The csproj switches to EnableMsixTooling +
   Microsoft.Windows.SDK.BuildTools + Microsoft.Windows.SDK.BuildTools.WinApp so
   'dotnet run' registers a loose package and launches with MSIX identity.
   templates.props sets RenameManifestFrom and the template.json files gain the
   publisher / guid / build-tools-version symbols and the \\$
   modifier.

2. Visually match their WinUI counterparts:
   - reactor      -> title bar (app icon) + empty content (blank canvas).
   - reactor-mvu  -> centered 'Hello, WinUI!' + [+]/[-] icon counter (keeps the
     UseReducer MVU pattern under the same UI).
   - reactor-navview -> title bar + NavigationView Home/About + built-in Settings;
     pages render 'Title' + 'This is the X page'.
   - reactor-tabview -> MicaAlt, app-icon TabStripHeader, closable Home/About tabs
     with a '+' add button, tabs in the title bar.

Validated end-to-end for all four: pack -> install -> scaffold -> build ->
dotnet run (launches packaged with identity) -> screenshot matches the WinUI
counterpart. README updated (templates are now packaged).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* reactor-mvu: greet 'Hello, Reactor!'; use WinUI type-ramp styles for font parity

- MVU greeting is now 'Hello, Reactor!' (was 'Hello, WinUI!').
- Switch the Reactor text from Heading()/.SemiBold() (raw 28px Bold-700) to the
  type-ramp factories Title()/BodyStrong()/Body(), which apply the actual WinUI
  styles (TitleTextBlockStyle 28px Semibold-600, BodyStrongTextBlockStyle,
  BodyTextBlockStyle). This makes the Reactor headings/body render with the same
  weight and Segoe UI Variable optical size as the WinUI templates instead of a
  heavier bold. Applied to the mvu, navview, and tabview page text.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* reactor-tabview: give tab pages a solid background to match WinUI

The WinUI TabView template's pages set Background=SolidBackgroundFillColorTertiaryBrush,
which covers the window's Mica in the tab content area. The Reactor version left
the pages transparent, so MicaAlt showed through the content. Wrap the tab page
content in a Border painted with that same tertiary brush so the content is a
solid surface and only the tab strip / title bar show Mica, matching X_Tab.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* reactor-tabview: stretch the tab page surface to fill the content area

The solid tertiary page background only covered the text at the top because
Reactor sizes the tab content to the element's desired size. Force the page
Border to HorizontalAlignment/VerticalAlignment Stretch so the solid surface
fills the whole tab content region, matching the WinUI TabView template
(verified: the content is a uniform solid fill down to the window bottom).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* Fill reactor-tabview page surface to window height

Match the WinUI TabView template's uniform tertiary content background by
sizing the shared page surface to the window height, so it fills the whole
tab content area instead of shrinking to its text (two-tone with Mica below).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 16d7d2fc-3d7c-41e8-9999-0c2084ba9ea1

* Use Reactor's navigation system in reactor-navview

Match the WinUI NavigationView template's shell: the title bar owns the back
and pane toggle buttons, and NavigationView's own copies are hidden.

Switch from hand-rolled tag state to Reactor's navigation handle
(UseNavigation + NavigationHost), so the title bar back button is wired by
.WithNavigation(nav) and tracks the back stack instead of never appearing.
Also request the tall title bar layout the WinUI template uses.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 16d7d2fc-3d7c-41e8-9999-0c2084ba9ea1

* Toggle the nav pane on the control instead of mirrored state

NavigationView opens and closes its pane on its own (light dismiss, display
mode changes), so a separate IsPaneOpen state copy drifted out of sync and
the title bar toggle needed two clicks to take effect.

Flip IsPaneOpen on the control directly, the same way the WinUI template's
code-behind does.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 16d7d2fc-3d7c-41e8-9999-0c2084ba9ea1

* Match the WinUI page transition in reactor-navview

Reactor's NavigationHost slides pages in from the side, while WinUI's Frame
defaults to an entrance transition that rises the new page up into place.
Slide from the bottom so switching pages animates the same way.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 16d7d2fc-3d7c-41e8-9999-0c2084ba9ea1

* Trim the Reactor templates to match the XAML templates' style

The Reactor templates carried long comments explaining Reactor concepts and
how they differ from XAML, which made them read like documentation rather
than a starting point. Keep only the brief, functional comments the XAML
templates use, and a single pointer to the Reactor project info.

Also drop the explicit navigation transition from reactor-navview: matching
the XAML Frame's entrance animation added verbosity and called out a
difference between the two, so use Reactor's default instead.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 16d7d2fc-3d7c-41e8-9999-0c2084ba9ea1

* Mark the Reactor templates as experimental

Microsoft.UI.Reactor is prerelease and its API may still change, so label the
templates accordingly: add `(Experimental)` to each template name, an
`Experimental` classification so it shows in the dotnet new tags column, and
a note in each description and in the README.

Also correct the templates.props comment, which still described the Reactor
apps as unpackaged with RenameManifestFrom unset; they are packaged
(single-project MSIX) and do set it.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 16d7d2fc-3d7c-41e8-9999-0c2084ba9ea1

* Fix Reactor analyzer warnings in the MVU and TabView templates

The templates tripped four of Reactor's analyzers, so a freshly scaffolded
project did not build clean:

- REACTOR_A11Y_001 (x2): the MVU counter's icon-only buttons had no
  accessible name. Add .AutomationName().
- REACTOR_A11Y_002: the TabView tab strip icon is decorative. Mark it
  .AccessibilityHidden().
- REACTOR_HOOKS_013: the initial tab array was reallocated on every render
  though only read on the first. Wrap it in UseMemo.
- REACTOR_POOL_001: the page surface set MinHeight via .Set(...), which is
  reset when the element returns to the pool, so the tab content fill could
  be lost on re-render. Use the .MinHeight() modifier instead.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 16d7d2fc-3d7c-41e8-9999-0c2084ba9ea1

* Use $targetentrypoint$ in the Reactor manifests, like the XAML templates

The Reactor manifests hardcoded EntryPoint=Windows.FullTrustApplication while
every XAML template uses the $targetentrypoint$ token. The token already
resolves to Windows.FullTrustApplication for these projects, so the generated
AppxManifest.xml is unchanged - this just removes an unexplained difference
between the two sets of templates.

The four Reactor manifests are now byte-identical to their XAML counterparts.

Verified: all four scaffold, build warning-free, generate the same
EntryPoint=Windows.FullTrustApplication, and launch with package identity.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 16d7d2fc-3d7c-41e8-9999-0c2084ba9ea1

* Commit the Reactor templates' publish profiles

The root .gitignore has a blanket `*.pubxml` rule, so the three publish
profiles in each Reactor template were silently never added. They existed
only on the authoring machine; a clean clone got none of them. The WinUI
templates force-added theirs in #6407 for the same reason.

Without the profiles the csproj's
`<PublishProfile Condition="Exists(...)">` never resolves, so SelfContained
is never set to true. Combined with PublishTrimmed=true for non-Debug
configurations that fails a Release build outright:

  error NETSDK1102: Optimizing assemblies for size is not supported for the
  selected publish configuration. Please ensure that you are publishing a
  self-contained app.

Force-add all 12 files so Release builds and publish work from a fresh
clone, matching the WinUI templates.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 16d7d2fc-3d7c-41e8-9999-0c2084ba9ea1

* Stop .gitignore from swallowing template publish profiles

The blanket `*.pubxml` rule silently ignored the Reactor templates' publish
profiles, so they were never committed and Release builds failed from a
clean clone (fixed in 8ea4586 by force-adding them).

`git add -f` fixed those 12 files but not the mechanism: the next template
added, or a new RID added to an existing one, hits the same trap and it is
again invisible to anyone whose working tree still has the files on disk.

Add a `!dev/Templates/**/*.pubxml` negation alongside the existing one for
dev/vsix, so template publish profiles are committable by default. Publish
profiles elsewhere in the repo stay ignored.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 16d7d2fc-3d7c-41e8-9999-0c2084ba9ea1

* Match the XAML templates' icon font and size

The Reactor templates hardcoded `Segoe Fluent Icons` on their FontIcons and
left the size at WinUI's default. The XAML templates do neither: they use
`<FontIcon Glyph="..." />` with no FontFamily, inheriting SymbolThemeFontFamily,
which resolves the right icon font for the OS — worth keeping given the
templates support Windows 10 1809 and Segoe Fluent Icons is Windows 11 era.

The MVVM template also sets FontSize="14" on its counter icons, which ours
missed, so the buttons rendered larger than their XAML counterpart:

  XAML MVVM      58x41
  Reactor MVU    67x51  ->  58x42

Verified against Microsoft.UI.Reactor 0.1.0-preview.12: both templates build
warning-free and the glyphs render correctly (Icon(FontIcon(...)) resolves
through IconResolver, not the Button(string) content path).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 16d7d2fc-3d7c-41e8-9999-0c2084ba9ea1

* Update Reactor dotnet new templates for 0.1.0-preview.13

Reactor preview.13 adds declarative APIs that let the Navigation and
TabView templates drop their imperative escape hatches:

- NavigationView: use IsBackButtonVisible / IsPaneToggleButtonVisible and
  .IsPaneOpen(value, handler) instead of UseRef + OnMount downcast, and
  select the built-in Settings item via NavigationViewElement.SettingsTag.
  OnSelectedTagChanged still reports null for Settings by design, so
  TagToRoute keeps handling both SettingsTag and null.
- TitleBar: use .Tall() instead of the UseEffect + DispatcherQueue hop and
  the redundant .Height(48).
- TabView: set FillContentArea, removing the MinHeight workaround.

Also bump the reactorVersion default to 0.1.0-preview.13 in all four
Reactor template.json files.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 38f0823a-2ee4-4c65-8f3f-7dde6a049509

* Let the OS size the window, like the XAML templates

Drop the hardcoded 1000x700 from all four Reactor templates. Reactor
PR #924 makes ReactorApp.Run's width/height optional, so omitting them
lets the OS pick the size, matching the XAML templates which set no
size at all. Verified identical to a freshly scaffolded XAML app.

This requires 0.1.0-preview.13; before #924, omitting width/height
meant a hardcoded 1024x768 rather than an OS-chosen size.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 38f0823a-2ee4-4c65-8f3f-7dde6a049509

* Add the MsixPackage launch profile to the Reactor templates

The Reactor templates were originally unpackaged and their launchSettings.json
only declared `commandName: Project` profiles. Making them single-project MSIX
updated the csproj and added Package.appxmanifest but left launchSettings
behind, so F5 from Visual Studio failed:

  ...launchSettings.json does not contain a profile with commandName
  'MsixPackage'. To debug a packaged single-project MSIX solution, a profile
  with command name MsixPackage in launchSettings.json is required.

`dotnet run` goes through Microsoft.Windows.SDK.BuildTools.WinApp instead, so
it worked throughout and the gap went unnoticed.

Declare the same Package / Unpackaged pair the WinUI XAML templates ship, with
Package first so it is the F5 default, and keep the Reactor devtools profile
alongside them.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 16d7d2fc-3d7c-41e8-9999-0c2084ba9ea1

* Float the Windows App SDK version in the Reactor templates

The Reactor templates pinned Microsoft.WindowsAppSDK to 2.1.3 while the WinUI
XAML templates default to `*`. That pinned new projects to an older SDK than
the one Visual Studio offers everywhere else — 2.3.1 is current, so scaffolded
Reactor apps were two releases behind for no reason.

2.1.3 was the version Reactor happened to be built against, not a hard floor:
Microsoft.UI.Reactor 0.1.0-preview.13 depends on Microsoft.WindowsAppSDK.WinUI
>= 2.1.0. Keep the requirement in the parameter description rather than
encoding it as the pin, matching the WinUI templates.

Verified with the floated default: all four templates resolve
Microsoft.WindowsAppSDK 2.3.1, build warning-free, and launch with package
identity.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 16d7d2fc-3d7c-41e8-9999-0c2084ba9ea1

* Accept MSB4181 for the invalid-version restore test on .NET SDK 10

The dotnet-new template test stage previously installed only the .NET 8 SDK.
Adding the .NET 10 SDK (needed because the Reactor templates target net10.0)
means the muxer now selects 10.0.400 for the pre-existing winui negative
tests as well, which changes the diagnostic NuGet emits for an unparseable
package version:

  SDK 8.0.424 / 9.0.317 : no error code; "'not-a-version' is not a valid
                          version string."
  SDK 10.0.400          : MSB4181 - RestoreTask returns false without
                          logging the descriptive error, so no NU code
                          surfaces at all.

The old assertion short-circuited on any error code being present and
demanded NU1105, so MSB4181 failed the run. (NU1105 never actually
surfaced on any tested SDK; the test passed via the descriptive-message
fallback.) Accept NU1105/MSB4181 or the descriptive message, and stop a
code's presence from bypassing the fallback.

Verified on 8.0.424 / 9.0.317 / 10.0.400. Unrelated failures (NU1101,
NU1301) still fail the assertion, so it is not weakened to "any failure".
Scenario 5's build check (NETSDK1004), scenario 6 (NU1102) and scenario 7
(NU1301) were confirmed unchanged on SDK 10.

Also corrects an adjacent comment that said NETSDK1005 where the check and
the observed behaviour are both NETSDK1004.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 16d7d2fc-3d7c-41e8-9999-0c2084ba9ea1

* Pin the Reactor test-stage .NET SDK instead of floating 10.0.x

Every other UseDotNet@2 task in this repo pins an exact SDK (6.0.414,
6.0.427, 8.0.100, 9.0.200, 10.0.111); #6624 added the BuildVSIX pin so
Component Governance scans a patched toolchain, and #6699 bumped it
deliberately for a security release. reactorDotnetSdkVersion was the only
new floating pin.

Floating is what broke CI: '10.0.x' resolved to 10.0.302 when the task was
added on 2026-07-23, then silently jumped a whole feature band when 10.0.400
shipped on 2026-08-11. 10.0.400 changed the NuGet diagnostic for an
unparseable package version, so the pre-existing winui invalid-version smoke
test started failing with no corresponding source change.

Pinned to 10.0.400 rather than the 10.0.111 used by BuildVSIX. The Reactor
templates cannot use the 1xx servicing band: Microsoft.UI.Reactor's analyzers
and source generators (Reactor.Analyzers, Reactor.Wrappers.Generator,
Reactor.Localization.Generator) reference Roslyn 5.6.0.0, and 10.0.111 ships
Roslyn 5.0.0.0, so all three are silently disabled with CS9057 while the
build still reports success. Verified by building the same scaffolded project
on both SDKs: 10.0.111 -> 3x CS9057, 10.0.400 (Roslyn 5.9.0.0) -> 0 warnings.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 16d7d2fc-3d7c-41e8-9999-0c2084ba9ea1

* Accept NETSDK1005 for the invalid-version build test on .NET SDK 10

Follow-up to 5ff625e, which fixed the restore assertion in the same
scenario. The build assertion immediately after it failed for the same
underlying reason.

On .NET SDK 10 NuGet's RestoreTask fails (MSB4181) but still writes a
partial obj/project.assets.json. The subsequent --no-restore build therefore
reports NETSDK1005 (assets file has no target for the project's TFM) rather
than NETSDK1004 (assets file missing). Accept either, since both mean restore
did not produce usable assets. Scenario 7's list gains NETSDK1005 for the
same reason; it currently resolves to NU1301, but NETSDK1004 is in that list
for the 'restore never succeeded' case whose SDK 10 equivalent is 1005.

This also reverts the NETSDK1005 -> NETSDK1004 comment change from 5ff625e.
That comment was correct as written; I changed it based on a repro that used
a bare net8.0 project with no obj directory, which produces NETSDK1004 and
does not reproduce the real template's behaviour. Re-verified with a faithful
repro (net10.0-windows10.0.26100.0, WinUI props, same build flags), which
reproduces CI exactly: assets file present after the failed restore, build
fails with NETSDK1005.

All four error-code assertions in this script are now backed by faithful
repros on the pinned SDK 10.0.400: restore MSB4181, build NETSDK1005,
scenario 6 NU1102, scenario 7 NU1301. Unrelated failures still throw.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 16d7d2fc-3d7c-41e8-9999-0c2084ba9ea1

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 16d7d2fc-3d7c-41e8-9999-0c2084ba9ea1
Copilot-Session: 38f0823a-2ee4-4c65-8f3f-7dde6a049509
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants