diff --git a/aspnetcore/blazor/hybrid/tutorials/index.md b/aspnetcore/blazor/hybrid/tutorials/index.md index 92a40a5a9159..b901e73704ba 100644 --- a/aspnetcore/blazor/hybrid/tutorials/index.md +++ b/aspnetcore/blazor/hybrid/tutorials/index.md @@ -15,4 +15,6 @@ uid: blazor/hybrid/tutorials/index * +* + For more information on Blazor hosting models, see . diff --git a/aspnetcore/blazor/hybrid/tutorials/windows-forms.md b/aspnetcore/blazor/hybrid/tutorials/windows-forms.md new file mode 100644 index 000000000000..b86b0b334979 --- /dev/null +++ b/aspnetcore/blazor/hybrid/tutorials/windows-forms.md @@ -0,0 +1,256 @@ +--- +title: Build a Windows Forms Blazor app +author: guardrex +description: Build a Windows Forms Blazor app step-by-step. +monikerRange: '>= aspnetcore-6.0' +ms.author: riande +ms.custom: mvc +ms.date: 02/15/2022 +no-loc: [Home, Privacy, Kestrel, appsettings.json, "ASP.NET Core Identity", cookie, Cookie, Blazor, "Blazor Server", "Blazor WebAssembly", "Identity", "Let's Encrypt", Razor, SignalR] +uid: blazor/hybrid/tutorials/windows-forms +--- +# Build a Windows Forms Blazor app + +This tutorial shows you how to build and run a Windows Forms Blazor app. You learn how to: + +> [!div class="checklist"] +> * Create a Windows Forms Blazor app project +> * Run the app on Windows + +## Prerequisites + +* [Supported platforms (Windows Forms documentation)](/dotnet/desktop/winforms/overview/) +* [Visual Studio 2022 Preview](https://visualstudio.microsoft.com/vs/preview/) with the **.NET desktop development** workload + +## Visual Studio workload + +If the **.NET desktop development** workload isn't installed, use the Visual Studio installer to install the workload: + +:::image type="content" source="windows-forms/_static/install-workload.png" alt-text="Visual Studio installer .NET desktop development workload selection."::: + +## Create a Windows Forms Blazor project + +Start Visual Studio 2022 Preview. Select **Create a new project**. + +In the **Create a new project** dialog, select the C# project template **Windows Forms App** and select the **Next** button: + +:::image type="content" source="windows-forms/_static/create-project.png" alt-text="Create a new project in Visual Studio."::: + +In the **Configure your new project** dialog, set the **Project name** to **`WinFormsBlazor`**, choose a suitable location for the project, and select the **Next** button. Using `WinFormsBlazor` as the project name matches the donor Blazor project names created in the preceding section, which aligns the namespaces of the three projects. + +:::image type="content" source="windows-forms/_static/configure-project.png" alt-text="Configure the project."::: + +In the **Additional information** dialog, select the framework version, which must be .NET 6.0 or later. Select the **Create** button. + +Use [NuGet Package Manager](/nuget/consume-packages/install-use-packages-visual-studio) to install the [`Microsoft.AspNetCore.Components.WebView.WindowsForms`](https://nuget.org/packages/Microsoft.AspNetCore.Components.WebView.WindowsForms) preview NuGet package. + +In **Solution Explorer**, right-click the project's name, `WinFormsBlazor` and select **Edit Project File** to open the project file (`WinFormsBlazor.csproj`). + +At the top of the project file, change the SDK to `Microsoft.NET.Sdk.Razor`: + +```xml + +``` + +Add the following [MSBuild `Content` item](/visualstudio/msbuild/common-msbuild-project-items#content) to the project file, which copies the contents of the `wwwroot` folder to the output directory without compiling the assets in the folder: + +```xml + + + +``` + +Save the changes to the project file (`WinFormsBlazor.csproj`). + +Add an `_Imports.razor` file to the root of the project with an [`@using`](xref:mvc/views/razor#using) directive for . + +`_Imports.razor`: + +```razor +@using Microsoft.AspNetCore.Components.Web +``` + +Add a `wwwroot` folder to the project. + +Add an `index.html` file to the `wwwroot` folder with the following markup. + +`wwwroot\index.html`: + +```html + + + + + + WinFormsBlazor + + + + + + + +
Loading...
+ +
+ An unhandled error has occurred. + Reload + 🗙 +
+ + + + + + +``` + +Inside the `wwwroot` folder, create a `css` folder to hold stylesheets. + +Add an `app.css` stylesheet to the `wwwroot/css` folder with the following content. + +`wwwroot/css/app.css`: + +```css +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; + } +``` + +Add the following `Counter` component to the root of the project, which is the default `Counter` component found in Blazor project templates. + +`Counter.razor`: + +```razor +

Counter

+ +

Current count: @currentCount

+ + + +@code { + private int currentCount = 0; + + private void IncrementCount() + { + currentCount++; + } +} +``` + +In **Solution Explorer**, double-click on the `Form1.cs` file to open the designer: + +:::image type="content" source="windows-forms/_static/solution-explorer-1.png" alt-text="The Form1.cs file in Solution Explorer."::: + +Open the **Toolbox** by either selecting the **Toolbox** button along the left edge of the Visual Studio window or selecting the **View** > **Toolbox** menu item. + +Locate the `BlazorWebView` control under `Microsoft.AspNetCore.Components.WebView.WindowsForms`: + +:::image type="content" source="windows-forms/_static/toolbox.png" alt-text="BlazorWebView in the Toolbox."::: + +Drag `BlazorWebView` from the **Toolbox** into the `Form1` designer: + +:::image type="content" source="windows-forms/_static/form1.png" alt-text="BlazorWebView in the Form1 designer."::: + +In `Form1`, select `BlazorWebView` with a single click. + +In `BlazorWebView`'s **Properties**, change its **Dock** value to **Fill**: + +:::image type="content" source="windows-forms/_static/properties.png" alt-text="BlazorWebView properties with Dock set to Fill."::: + +In the `Form1` designer, right-click `Form1` and select **View Code**. + +Add namespaces for `Microsoft.AspNetCore.Components.WebView.WindowsForms` and to the top of the `Form1.cs` file: + +```csharp +using Microsoft.AspNetCore.Components.WebView.WindowsForms; +using Microsoft.Extensions.DependencyInjection; +``` + +Inside the `Form1` constructor, below the `InitializeComponent()` method call, add the following code: + +```csharp +var services = new ServiceCollection(); +services.AddBlazorWebView(); +blazorWebView1.HostPage = "wwwroot\\index.html"; +blazorWebView1.Services = services.BuildServiceProvider(); +blazorWebView1.RootComponents.Add("#app"); +``` + +The final, complete C# code of `Form1.cs`: + +```csharp +using Microsoft.AspNetCore.Components.WebView.WindowsForms; +using Microsoft.Extensions.DependencyInjection; + +namespace WinFormsBlazor +{ + public partial class Form1 : Form + { + public Form1() + { + InitializeComponent(); + + var services = new ServiceCollection(); + services.AddBlazorWebView(); + blazorWebView1.HostPage = "wwwroot\\index.html"; + blazorWebView1.Services = services.BuildServiceProvider(); + blazorWebView1.RootComponents.Add("#app"); + } + } +} +``` + +## Run the app + +Select the start button in the Visual Studio toolbar: + +:::image type="content" source="windows-forms/_static/start-button.png" alt-text="Start button of the Visual Studio toolbar."::: + +The app running on Windows: + +:::image type="content" source="windows-forms/_static/running-app.png" alt-text="The app running on Windows."::: + +## Next steps + +In this tutorial, you learned how to: + +> [!div class="checklist"] +> * Create a Windows Forms Blazor app project +> * Run the app on Windows + +Learn more about Blazor Hybrid apps: + +> [!div class="nextstepaction"] +> diff --git a/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/configure-project.png b/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/configure-project.png new file mode 100644 index 000000000000..23c6662fc499 Binary files /dev/null and b/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/configure-project.png differ diff --git a/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/create-project.png b/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/create-project.png new file mode 100644 index 000000000000..55646b919c13 Binary files /dev/null and b/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/create-project.png differ diff --git a/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/form1.png b/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/form1.png new file mode 100644 index 000000000000..0f71fc3a2af3 Binary files /dev/null and b/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/form1.png differ diff --git a/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/install-workload.png b/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/install-workload.png new file mode 100644 index 000000000000..572b1c213efb Binary files /dev/null and b/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/install-workload.png differ diff --git a/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/properties.png b/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/properties.png new file mode 100644 index 000000000000..7c1517ed93ea Binary files /dev/null and b/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/properties.png differ diff --git a/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/running-app.png b/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/running-app.png new file mode 100644 index 000000000000..a77ba888ff06 Binary files /dev/null and b/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/running-app.png differ diff --git a/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/solution-explorer-1.png b/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/solution-explorer-1.png new file mode 100644 index 000000000000..7a80ab393c53 Binary files /dev/null and b/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/solution-explorer-1.png differ diff --git a/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/start-button.png b/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/start-button.png new file mode 100644 index 000000000000..6aa046749140 Binary files /dev/null and b/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/start-button.png differ diff --git a/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/toolbox.png b/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/toolbox.png new file mode 100644 index 000000000000..76789292d068 Binary files /dev/null and b/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/toolbox.png differ diff --git a/aspnetcore/toc.yml b/aspnetcore/toc.yml index 1b2b474ae734..d57afdf4e03d 100644 --- a/aspnetcore/toc.yml +++ b/aspnetcore/toc.yml @@ -345,6 +345,8 @@ items: uid: blazor/hybrid/tutorials/index - name: .NET MAUI uid: blazor/hybrid/tutorials/maui + - name: Windows Forms + uid: blazor/hybrid/tutorials/windows-forms - name: Project structure uid: blazor/project-structure - name: Fundamentals