AspNetCore.Docs
AspNetCore.Docs copied to clipboard
Match Blazor Hybrid WPF/WinForms project structure to .NET MAUI-Blazor
What is the recommended folder structure for Blazor Hybrid projects?
More specifically, the documentation states that "MainLayout.razor" should be in folder "ProjectRoot\Shared". in a Blazor Hybrid(WPF) project, where should this file be to have any effect?
Document Details
β Do not edit this section. It is required for docs.microsoft.com β GitHub issue linking.
- ID: d31248d7-d2c2-1a17-3173-889a0d9bb6e8
- Version Independent ID: 6f27ff37-6b3a-57f5-353a-5cf5aabba7cf
- Content: ASP.NET Core Blazor project structure
- Content Source: aspnetcore/blazor/project-structure.md
- Product: aspnet-core
- Technology: aspnetcore-blazor
- GitHub Login: @guardrex
- Microsoft Alias: riande
Hello @tecxx ... The Blazor topic within the general Blazor node is more directly aimed at the Blazor WebAssembly and Blazor Server projects. There's a lot of overlap, of course, with Blazor Hybrid. It might be a good idea for us to have a standalone topic for Blazor Hybrid project structure in the Blazor Hybrid node. I'll ask management about it when we all get back. A few of us are OOF this week (vacations ποΈπΉ, for example), then there's the 3-day holiday weekend ππ§¨. I'll ping the following week.
For that specific question, the Shared
folder is used by convention, and you'll see @using {ASSEMBLY NAME}.Shared
in the _Imports.razor
file. You can use your own folders for shared components, and they become part of the "shared" components' namespace. You need to make sure that you either use a fully-qualified namespace for such components in your custom folder OR add your custom folder namespace to the _Imports.razor
file (e.g., if one places some components to share in a CustomSharedStuff
folder in the app with an assembly name of BlazorApp
, they would place a @using BlazorApp.CustomSharedStuff
into _Imports.razor
. You can then use your components in the CustomSharedStuff
throughout the app's other Razor components. That's the typical way to go over using fully-qualified assembly names of the shared components.
Cross-ref for our docs on that subject: https://docs.microsoft.com/aspnet/core/blazor/components/#namespaces
As it stands today for Blazor Hybrid (WPF) project structure, look at the guidance for modifying a base WPF app and described in Build a Windows Presentation Foundation (WPF) Blazor app. That article describes indirectly what the current conventions are by virtue of its instructions on how to set up the app. Later, they may create a WPF-Blazor project template that devs can look at, either by creating an app from the template and looking at it or by looking at the project template's reference source. Today, there is no WPF-Blazor template, but there might be one in the future.
Leave this issue open, and we'll explore having a separate Blazor Hybrid project structure topic when we all get back after July 4.
hy, thanks for the quick and detailed answer. don't worry, i'll be on holiday as well ;)
well i followed the instructions at https://docs.microsoft.com/en-gb/aspnet/core/blazor/hybrid/tutorials/wpf?view=aspnetcore-6.0 closely, but can't get my app to work correctly. i'm trying to use Radzen Blazor (as we do in our server-side project already), and the installation instructions (step 6 - https://blazor.radzen.com/get-started) mention to add the following to MainLayout.razor
<RadzenDialog/> <RadzenNotification/> <RadzenContextMenu/> <RadzenTooltip/>
as "MainLayout.razor" is not part of the blazor hybrid example instructions, i added it manually to the folder "Shared".
however i can't utilize e.g. the RadzenDialog component. the dialogs just won't appear.
when i specifically add the tag <RadzenDialog/> to one of my pages, it works as expected. this led me to believe that maybe my MainLayout.razor file is not in the correct place and gets ignored?
sample project: https://github.com/tecxx/BlazorHybridWPF-Radzen
Try adding ...
@layout MainLayout
... to your root component (in the WPF-Blazor tutorial, it would be added at the top of the Counter
component). I haven't played around with layouts in WPF-Blazor Hybrid apps (yet), but that would be the normal way to apply it outside of specifying the layout in a non-root imports file (i.e., don't place an @layout
in the root _Imports.razor
because it leads to an infinite loop).
Cross-ref: https://docs.microsoft.com/aspnet/core/blazor/components/layouts?view=aspnetcore-6.0#apply-a-layout-to-a-component
BTW --- I really, really shouldn't be looking at this π. I'm very much in need of a break for a few days, but I find it hard to get away from the bits. I don't like leaving folks hang'in, but I need to take some time off π β±οΈ. Since I can't help further until next week, I recommend taking it up with the community on a public support forum. We recommend the usual spots ...
I slept on this, and I think whether or not management wants a separate article on Blazor Hybrid project structure that we should address the inconsistency in the tutorials on the layout point.
The MAUI-Blazor experience (the project template), uses a Main
component as the root component ...
<RootComponent Selector="#app" ComponentType="{x:Type local:Main}" />
Main
component holds a Router
component with ...
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
...
<LayoutView Layout="@typeof(MainLayout)">
...
... and there you see the MainLayout
set as the default layout and the layout view for the message shown when routes aren't found.
We don't take the Main
/Router
component approach in the WPF and WinForms tutorials to set a default layout.
WinForms sets the Counter
component as the root component in Form1
without a layout ...
blazorWebView1.RootComponents.Add<Counter>("#app");
WPF sets it in MainWindow
without a layout ...
<blazor:RootComponent Selector="#app" ComponentType="{x:Type local:Counter}" />
It might be nice to align these experiences with layouts, if it makes sense to do so. I'm still picking up desktop/mobile dev, and it might be that for WinForms/WPF the layout is typically provided by those frameworks outside of the root component. If so, then we'd probably remark on that delta in passing in the WinForms and WPF tutorials.
Anyway ... I'm still not here. I'm on vacation β±οΈπΉ. We'll look at this further when I get back. This comment was placed by my automated response RexBOTβ’ π¦π€! π€£
FYI, we're working our way back to this. There will be a delay of some length due to high priority .NET 7 work by the product unit and some setup work that I need to do for doc issues and other higher priority doc issues. We'll get back to this ASAP ππ .
I'm going to go ahead and schedule this for work, but it's going to be a low priority work item in light of getting the .NET 7 docs done by November and the mop-up on the release immediately after. Then, the π holiday season βοΈ lands. I suspect that the earliest this can be reached is 23Q1.
UPDATE (2/6): This is still on my radar. We're now past the annual November release π and past the new year's push to resolve many lingering backlog issues π . I can't quite reach it YET because I need to work through and update Blazor's Security node guidance π , which has been languishing for a few years as a lower priority task now elevated to a high priority task.
However, I still hope to reach this soon-ish π. I definitely want to resolve it in H1 of this year before .NET 8 content starts to land in force.
thanks for the update, no worries, this has no urgency at all. focus is still on blazor server here. ;)
Ultimately, this issue won't be pursued because WinForms-Blazor and WPF-Blazor only exist as transition support for WinForms and WPF apps moving to Blazor adoption with .NET MAUI. Therefore, we won't invest more time in supporting these scenarios. We'll merely check periodically on releases that the existing guidance works as provided.