Blazor Hybrid WinForms tutorial (PR3)#24989
Conversation
There was a problem hiding this comment.
Thanks for putting this together, @guardrex.
I would prefer to simplify this tutorial to setup a single Razor component instead of the entire default Blazor project template. That should allow us to give inline instructions instead of copying from other projects.
Here are the high-level steps that I'd like to use:
- Create a new Windows Forms app
- Install the Microsoft.AspNetCore.Components.WebView.WindowsForms using the NuGet package manager
- Update the .csproj file to change the SDK to
Microsoft.NET.Sdk.Razor - Add an _Imports.razor file with
@using Microsoft.AspNetCore.Components.Web - Add a wwwroot folder
- Add wwwroot\index.html with the following:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>WinFormsApp1</title>
<base href="/" />
<link href="css/app.css" rel="stylesheet" />
<link href="WinFormsApp1.styles.css" rel="stylesheet" />
</head>
<body>
<div id="app">Loading...</div>
<div id="blazor-error-ui">
An unhandled error has occurred.
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>
<script src="_framework/blazor.webview.js"></script>
</body>
</html>- Add wwwroot/css/app.css with the following
html, body {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
.valid.modified:not([type=checkbox]) {
outline: 1px solid #26b050;
}
.invalid {
outline: 1px solid red;
}
.validation-message {
color: red;
}
#blazor-error-ui {
background: lightyellow;
bottom: 0;
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
display: none;
left: 0;
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
position: fixed;
width: 100%;
z-index: 1000;
}
#blazor-error-ui .dismiss {
cursor: pointer;
position: absolute;
right: 0.75rem;
top: 0.5rem;
}- Update the .csproj file to copy
wwwroot\**to the output directory:
I'm following up on how we can get rid of this step but for now I think it's needed.
<ItemGroup>
<Content Update="wwwroot\**" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>- Add a Counter.razor file with the default
Countercomponent code.
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}- Double-click on
Form1.csto open the designer. - Use View > Toolbox, and find
BlazorWebView - Drag
BlazorWebViewinto theForm1designer. - Right-click on this new item and choose Properties. Change its Dock value to Fill by clicking on the central rectangle:
- Inside the
Form1constructor, underneathInitializeComponent(), add the following code:
var services = new ServiceCollection();
services.AddBlazorWebView();
blazorWebView1.HostPage = "wwwroot\\index.html";
blazorWebView1.Services = services.BuildServiceProvider();
blazorWebView1.RootComponents.Add<Counter>("#app");- Run the app.
Sure thing. 👍 Due to the need to rewrite this, I probably won't have the WPF tutorial up until Wednesday morning. When I reach it, I'll write the WPF tutorial in the same vein as the rewrite guidance. |
|
❓s on the updates ...
|
I don't believe other namespaces are required, so let's keep it minimalistic.
Sure, WinFormsBlazor is fine.
Yeah, let's leave it. It is a bit weird that it doesn't get generated if you don't have any component specific styles, but I think you'll need it pretty quickly.
Nah, your Win10 snapshots are fine. |
|
I'll be on stand-by for feedback and updates. I'm around the 🏠 all day right into the evening ... WELL ... until the US Curling Teams get on the ice! Go Team Tabitha!Go Team Shuster! |
Co-authored-by: Daniel Roth <daroth@microsoft.com>


Addresses #24956
Internal Review Topic
Naming ...