Skip to content

feat: Multi Window Support#72

Open
0xApp wants to merge 1 commit intoDotNetExtension:mainfrom
0xApp:main
Open

feat: Multi Window Support#72
0xApp wants to merge 1 commit intoDotNetExtension:mainfrom
0xApp:main

Conversation

@0xApp
Copy link

@0xApp 0xApp commented Feb 26, 2026

Multi Window Support

Summary

  • Add IWindowManager service for opening and managing multiple desktop windows, each with an independent Blazor component tree
  • Add Razor component for declarative window management (open on render, close on dispose)
  • Refactor BlazorDesktopWindow to accept WindowOptions POCO instead of reading IConfiguration directly, enabling child windows with custom settings
  • Add multi-window demo page to BlazorDesktop.Sample showcasing both service-based and component-based APIs
  • Update README with multi-window documentation, API reference, and updated examples

New files

  • Hosting/WindowOptions.cs - Per-window configuration POCO with FromConfiguration() factory
  • Hosting/DesktopWindowHandle.cs - Lightweight handle to a managed window (Id, IsMainWindow, Closed event)
  • Services/IWindowManager.cs - Public interface: OpenAsync(), CloseAsync(), MainWindow, events
  • Services/WindowManager.cs - Internal implementation with ConcurrentDictionary tracking, WPF Dispatcher marshaling
  • Components/DesktopWindow.cs - Blazor component wrapping IWindowManager for declarative usage

Modified files

  • Wpf/BlazorDesktopWindow.cs - Added internal constructor accepting WindowOptions + RootComponentMappingCollection; replaced all IConfiguration reads with _options field
  • Hosting/BlazorDesktopHostBuilder.cs - Replaced BlazorDesktopWindow singleton with IWindowManager/WindowManager singleton
  • Services/BlazorDesktopService.cs - Creates BlazorDesktopWindow manually on STA thread; registers with WindowManager

Breaking change

BlazorDesktopWindow is no longer registered in the DI container. Code that injected it directly must use IWindowManager.MainWindow.NativeWindow instead.

Test plan

  • dotnet build BlazorDesktop.sln succeeds with 0 warnings/errors
  • Run BlazorDesktop.Sample, verify main window works identically to before
  • Navigate to Multi-Window page, click "Open Window (Service)" - child window opens with correct title/size and independent counter
  • Click "Open Window (Component)" - toggle opens/closes a declarative child window
  • Close a child window via X button - Closed event fires, window count updates, main app stays open
  • Close main window - all child windows close and app exits

@0xApp 0xApp mentioned this pull request Feb 26, 2026
1 task
@0xApp 0xApp changed the title Multi Window Support feat: Multi Window Support Feb 26, 2026
@russkyc
Copy link

russkyc commented Feb 28, 2026

This is how i would imagine #42 would be api-wise, @andrewbabbittdev what do you think?

@andrewbabbittdev
Copy link
Collaborator

andrewbabbittdev commented Feb 28, 2026

Mmmm generally prefer to start with a design proposal before starting on a PR @russkyc I would still like to see one filled out to go with this PR. It is under the issue templates.

I just got back from vacation so I wont have time to go over this for a little as I catch up on work and other stuff.

@andrewbabbittdev
Copy link
Collaborator

Took a peek over things, and yeah would still like to see a design doc for this.

As I stated in #42

I'd like to start taking API proposals to figure out how this feature should actually function before we start any coding work as there are quite a few ways this could be implemented and each have their own pros and cons.

On top of implementing this feature, I would also like for the proposed solution to address #55 and #65

While moving to options for configuration is nice, it really doesn't get us closer to where we want to be; which is better accessibility to window configuration. Instead we could probably just use configuration binding directly to the windows then pass the window directly as the configure object: https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.configuration.configurationbinder.bind?view=net-10.0-pp

Root components in this PR are being configured statically as #app which is not ideal, we let users configure this in Program.cs as Blazor Wasm lets users do.

This does bring the question of how these should be done as well, as there are multiple options with different tradeoffs (again, this is why we ask for design proposals BEFORE starting coding work 🙂). This also gets into how navigation works with Blazor.

You have a user select a specific component to display, but what about url based routing? Why not just setup child windows the same way as the main window and use the BlazorWebView.StartPath property instead to let the user route to a specific page in the newly created window?

I also just looked at NavigationManager in the docs and noticed it was abstract, meaning we could extend it to add our own navigate method that does the navigation in a new window. This is a pattern users in Blazor are already familiar with, and would be ideal from an API design perspective.

STAThread (#65) still ideally needs to be resolved as a part of this.

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.

3 participants