diff --git a/aspnetcore/blazor/hybrid/tutorials/index.md b/aspnetcore/blazor/hybrid/tutorials/index.md index b901e73704ba..447ced159ac1 100644 --- a/aspnetcore/blazor/hybrid/tutorials/index.md +++ b/aspnetcore/blazor/hybrid/tutorials/index.md @@ -17,4 +17,6 @@ uid: blazor/hybrid/tutorials/index * +* + For more information on Blazor hosting models, see . diff --git a/aspnetcore/blazor/hybrid/tutorials/maui.md b/aspnetcore/blazor/hybrid/tutorials/maui.md index 52be9ffa9a02..2d320692a5a1 100644 --- a/aspnetcore/blazor/hybrid/tutorials/maui.md +++ b/aspnetcore/blazor/hybrid/tutorials/maui.md @@ -27,7 +27,9 @@ This tutorial shows you how to build and run a .NET MAUI Blazor app. You learn h ## Create a .NET MAUI Blazor app -Launch Visual Studio 2022 Preview. In the start window, select **Create a new project**: +Launch Visual Studio 2022 Preview. + +In the Start Window, select **Create a new project**: :::image type="content" source="maui/_static/new-solution.png" alt-text="New solution."::: diff --git a/aspnetcore/blazor/hybrid/tutorials/windows-forms.md b/aspnetcore/blazor/hybrid/tutorials/windows-forms.md index b86b0b334979..fc27743afd18 100644 --- a/aspnetcore/blazor/hybrid/tutorials/windows-forms.md +++ b/aspnetcore/blazor/hybrid/tutorials/windows-forms.md @@ -24,23 +24,29 @@ This tutorial shows you how to build and run a Windows Forms Blazor app. You lea ## Visual Studio workload -If the **.NET desktop development** workload isn't installed, use the Visual Studio installer to install the workload: +If the **.NET desktop development** workload isn't installed, use the Visual Studio installer to install the workload. For more information, see [Modify Visual Studio workloads, components, and language packs](/visualstudio/install/modify-visual-studio). :::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**. +Start Visual Studio 2022 Preview. -In the **Create a new project** dialog, select the C# project template **Windows Forms App** and select the **Next** button: +In the Start Window, select **Create a new project**: + +:::image type="content" source="windows-forms/_static/new-solution.png" alt-text="Create a new solution in Visual Studio."::: + +In the **Create a new project** dialog, filter the **Project type** drop-down to **Desktop**. Select the C# project template for **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. +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. :::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. +In the **Additional information** dialog, select the framework version, which must be .NET 6.0 or later. Select the **Create** button: + +:::image type="content" source="windows-forms/_static/additional-information.png" alt-text="The Additional Information dialog."::: 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. @@ -74,7 +80,7 @@ Add a `wwwroot` folder to the project. Add an `index.html` file to the `wwwroot` folder with the following markup. -`wwwroot\index.html`: +`wwwroot/index.html`: ```html diff --git a/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/additional-information.png b/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/additional-information.png new file mode 100644 index 000000000000..0488c26e6f44 Binary files /dev/null and b/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/additional-information.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 index 55646b919c13..91d2d31a2fea 100644 Binary files a/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/create-project.png and b/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/create-project.png differ diff --git a/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/new-solution.png b/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/new-solution.png new file mode 100644 index 000000000000..a7b4e517a6d3 Binary files /dev/null and b/aspnetcore/blazor/hybrid/tutorials/windows-forms/_static/new-solution.png differ diff --git a/aspnetcore/blazor/hybrid/tutorials/wpf.md b/aspnetcore/blazor/hybrid/tutorials/wpf.md new file mode 100644 index 000000000000..c58e92f4b3d2 --- /dev/null +++ b/aspnetcore/blazor/hybrid/tutorials/wpf.md @@ -0,0 +1,302 @@ +--- +title: Build a Windows Presentation Foundation (WPF) Blazor app +author: guardrex +description: Build a Windows Presentation Foundation (WPF) app step-by-step. +monikerRange: '>= aspnetcore-6.0' +ms.author: riande +ms.custom: mvc +ms.date: 02/17/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/wpf +--- +# Build a Windows Presentation Foundation (WPF) Blazor app + +This tutorial shows you how to build and run a WPF Blazor app. You learn how to: + +> [!div class="checklist"] +> * Create a WPF Blazor app project +> * Supply Razor components with a Razor class library (RCL) +> * Run the app on Windows + +## Prerequisites + +* [Supported platforms (WPF documentation)](/dotnet/desktop/wpf/overview/) +* [Visual Studio 2022 Preview](https://visualstudio.microsoft.com/vs/preview/) with the following workloads: + * **ASP.NET and web development** + * **.NET desktop development** + +## Visual Studio workload + +If the **ASP.NET and web development** and **.NET desktop development** workloads aren't installed, use the Visual Studio installer to install the workloads. For more information, see [Modify Visual Studio workloads, components, and language packs](/visualstudio/install/modify-visual-studio). + +:::image type="content" source="wpf/_static/install-workloads.png" alt-text="Visual Studio installer workload selection."::: + +## Create a WPF Blazor project + +Start Visual Studio 2022 Preview. + +In the Start Window, select **Create a new project**: + +:::image type="content" source="wpf/_static/new-solution.png" alt-text="Create a new solution in Visual Studio."::: + +In the **Create a new project** dialog, filter the **Project type** drop-down to **Desktop**. Select the C# project template for **WPF Application** and select the **Next** button: + +:::image type="content" source="wpf/_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 **`WpfBlazor`**, choose a suitable location for the project, and select the **Next** button. + +:::image type="content" source="wpf/_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: + +:::image type="content" source="wpf/_static/additional-information-1.png" alt-text="The Additional Information dialog for the WPF project."::: + +## Add a component via a Razor class library (RCL) + +Add a Razor class library (RCL) project to the solution: + +In **Solution Explorer**, right-click the `WpfBlazor` solution and select **Add** > **New Project**: + +:::image type="content" source="wpf/_static/add-rcl-project.png" alt-text="Add a new RCL project to the solution in Visual Studio."::: + +In the **Create a new project** dialog, set the **Project types** drop-down to **Library**. Select the **Razor Class Library** project template and select the **Next** button: + +:::image type="content" source="wpf/_static/create-project-rcl.png" alt-text="Create a new RCL project in Visual Studio."::: + +In the **Configure your new project** dialog, set the **Project name** to **`ComponentLibrary`**. Confirm that the **Location** field is set to the solution's folder. Select the **Next** button: + +:::image type="content" source="wpf/_static/configure-project-rcl.png" alt-text="Configure the RCL project."::: + +In the **Additional information** dialog: + +* Select the framework version, which must be .NET 6.0 or later. +* Do ***not*** select the **Support pages and views** checkbox. +* Select the **Create** button. + +:::image type="content" source="wpf/_static/additional-information-2.png" alt-text="The Additional Information dialog for the Razor class library (RCL)."::: + +Add the following `Counter` component to the root of the RCL, 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++; + } +} +``` + +Add a project reference for the RCL to the `WpfBlazor` project: + +* In **Solution Explorer**, right-click the `WpfBlazor` project and select **Add** > **Project Reference**: + + :::image type="content" source="wpf/_static/add-rcl-project-reference.png" alt-text="Add a project reference to the WpfBlazor project."::: + +* Select the `ComponentLibrary`'s checkbox and select the **OK** button: + + :::image type="content" source="wpf/_static/add-componentlibrary.png" alt-text="Select the ComponentLibrary RCL project."::: + +For more information on RCLs for Blazor apps, see . + +## Configure the `WpfBlazor` solution + +Use [NuGet Package Manager](/nuget/consume-packages/install-use-packages-visual-studio) to install the [`Microsoft.AspNetCore.Components.WebView.Wpf`](https://nuget.org/packages/Microsoft.AspNetCore.Components.WebView.Wpf) preview NuGet package. + +In **Solution Explorer**, right-click the `WpfBlazor` project and select **Edit Project File** to open the project file (`WpfBlazor.csproj`). + +At the top of the project file, change the SDK to `Microsoft.NET.Sdk.Razor`: + +```xml + +``` + +Save the changes to the project file (`WpfBlazor.csproj`). + +Add a `wwwroot` folder to the project. + +Add an `index.html` file to the `wwwroot` folder with the following markup. + +`wwwroot/index.html`: + +```html + + + + + + + WpfBlazor + + + + + + + +
Loading...
+ +
+ An unhandled error has occurred. + Reload + 🗙 +
+ + + + +``` + +Inside the `wwwroot` folder, create a `css` folder. + +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; + } +``` + +If the `MainWindow` designer isn't open, open it by double-clicking the `MainWindow.xaml` file in **Solution Explorer**. In the `MainWindow` designer, replace the XAML code with the following: + +```xaml + + + + + + + + + +``` + +In **Solution Explorer**, right-click `MainWindow.xaml` and select **View Code**: + +:::image type="content" source="wpf/_static/view-mainwindow-code.png" alt-text="View MainWindow code."::: + +Add the namespace to the top of the `MainWindow.xaml.cs` file: + +```csharp +using Microsoft.Extensions.DependencyInjection; +``` + +Inside the `MainWindow` constructor, above the `InitializeComponent()` method call, add the following code: + +```csharp +var serviceCollection = new ServiceCollection(); +serviceCollection.AddBlazorWebView(); +Resources.Add("services", serviceCollection.BuildServiceProvider()); +``` + +The final, complete C# code of `MainWindow.xaml.cs`: + +```csharp +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using Microsoft.Extensions.DependencyInjection; + +namespace WpfBlazor +{ + /// + /// Interaction logic for MainWindow.xaml + /// + public partial class MainWindow : Window + { + public MainWindow() + { + var serviceCollection = new ServiceCollection(); + serviceCollection.AddBlazorWebView(); + Resources.Add("services", serviceCollection.BuildServiceProvider()); + + InitializeComponent(); + } + } +} +``` + +## Run the app + +Select the start button in the Visual Studio toolbar: + +:::image type="content" source="wpf/_static/start-button.png" alt-text="Start button of the Visual Studio toolbar."::: + +The app running on Windows: + +:::image type="content" source="wpf/_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 WPF Blazor app project +> * Supply Razor components with a Razor class library (RCL) +> * Run the app on Windows + +Learn more about Blazor Hybrid apps: + +> [!div class="nextstepaction"] +> diff --git a/aspnetcore/blazor/hybrid/tutorials/wpf/_static/add-componentlibrary.png b/aspnetcore/blazor/hybrid/tutorials/wpf/_static/add-componentlibrary.png new file mode 100644 index 000000000000..11b128c53fa0 Binary files /dev/null and b/aspnetcore/blazor/hybrid/tutorials/wpf/_static/add-componentlibrary.png differ diff --git a/aspnetcore/blazor/hybrid/tutorials/wpf/_static/add-rcl-project-reference.png b/aspnetcore/blazor/hybrid/tutorials/wpf/_static/add-rcl-project-reference.png new file mode 100644 index 000000000000..73c1b8e4b070 Binary files /dev/null and b/aspnetcore/blazor/hybrid/tutorials/wpf/_static/add-rcl-project-reference.png differ diff --git a/aspnetcore/blazor/hybrid/tutorials/wpf/_static/add-rcl-project.png b/aspnetcore/blazor/hybrid/tutorials/wpf/_static/add-rcl-project.png new file mode 100644 index 000000000000..78a6c07791a2 Binary files /dev/null and b/aspnetcore/blazor/hybrid/tutorials/wpf/_static/add-rcl-project.png differ diff --git a/aspnetcore/blazor/hybrid/tutorials/wpf/_static/additional-information-1.png b/aspnetcore/blazor/hybrid/tutorials/wpf/_static/additional-information-1.png new file mode 100644 index 000000000000..f9bddfe4cbef Binary files /dev/null and b/aspnetcore/blazor/hybrid/tutorials/wpf/_static/additional-information-1.png differ diff --git a/aspnetcore/blazor/hybrid/tutorials/wpf/_static/additional-information-2.png b/aspnetcore/blazor/hybrid/tutorials/wpf/_static/additional-information-2.png new file mode 100644 index 000000000000..e6f16d4d0315 Binary files /dev/null and b/aspnetcore/blazor/hybrid/tutorials/wpf/_static/additional-information-2.png differ diff --git a/aspnetcore/blazor/hybrid/tutorials/wpf/_static/configure-project-rcl.png b/aspnetcore/blazor/hybrid/tutorials/wpf/_static/configure-project-rcl.png new file mode 100644 index 000000000000..cb73f77ab56c Binary files /dev/null and b/aspnetcore/blazor/hybrid/tutorials/wpf/_static/configure-project-rcl.png differ diff --git a/aspnetcore/blazor/hybrid/tutorials/wpf/_static/configure-project.png b/aspnetcore/blazor/hybrid/tutorials/wpf/_static/configure-project.png new file mode 100644 index 000000000000..248133d03795 Binary files /dev/null and b/aspnetcore/blazor/hybrid/tutorials/wpf/_static/configure-project.png differ diff --git a/aspnetcore/blazor/hybrid/tutorials/wpf/_static/create-project-rcl.png b/aspnetcore/blazor/hybrid/tutorials/wpf/_static/create-project-rcl.png new file mode 100644 index 000000000000..daff43b32d03 Binary files /dev/null and b/aspnetcore/blazor/hybrid/tutorials/wpf/_static/create-project-rcl.png differ diff --git a/aspnetcore/blazor/hybrid/tutorials/wpf/_static/create-project.png b/aspnetcore/blazor/hybrid/tutorials/wpf/_static/create-project.png new file mode 100644 index 000000000000..ba6c0c13c013 Binary files /dev/null and b/aspnetcore/blazor/hybrid/tutorials/wpf/_static/create-project.png differ diff --git a/aspnetcore/blazor/hybrid/tutorials/wpf/_static/install-workloads.png b/aspnetcore/blazor/hybrid/tutorials/wpf/_static/install-workloads.png new file mode 100644 index 000000000000..da7929e8513f Binary files /dev/null and b/aspnetcore/blazor/hybrid/tutorials/wpf/_static/install-workloads.png differ diff --git a/aspnetcore/blazor/hybrid/tutorials/wpf/_static/new-solution.png b/aspnetcore/blazor/hybrid/tutorials/wpf/_static/new-solution.png new file mode 100644 index 000000000000..a7b4e517a6d3 Binary files /dev/null and b/aspnetcore/blazor/hybrid/tutorials/wpf/_static/new-solution.png differ diff --git a/aspnetcore/blazor/hybrid/tutorials/wpf/_static/running-app.PNG b/aspnetcore/blazor/hybrid/tutorials/wpf/_static/running-app.PNG new file mode 100644 index 000000000000..09bdf7bc533d Binary files /dev/null and b/aspnetcore/blazor/hybrid/tutorials/wpf/_static/running-app.PNG differ diff --git a/aspnetcore/blazor/hybrid/tutorials/wpf/_static/start-button.png b/aspnetcore/blazor/hybrid/tutorials/wpf/_static/start-button.png new file mode 100644 index 000000000000..6a33f905f1ab Binary files /dev/null and b/aspnetcore/blazor/hybrid/tutorials/wpf/_static/start-button.png differ diff --git a/aspnetcore/blazor/hybrid/tutorials/wpf/_static/view-mainwindow-code.png b/aspnetcore/blazor/hybrid/tutorials/wpf/_static/view-mainwindow-code.png new file mode 100644 index 000000000000..a8d1c11163c0 Binary files /dev/null and b/aspnetcore/blazor/hybrid/tutorials/wpf/_static/view-mainwindow-code.png differ diff --git a/aspnetcore/toc.yml b/aspnetcore/toc.yml index d57afdf4e03d..02602b131ea5 100644 --- a/aspnetcore/toc.yml +++ b/aspnetcore/toc.yml @@ -347,6 +347,8 @@ items: uid: blazor/hybrid/tutorials/maui - name: Windows Forms uid: blazor/hybrid/tutorials/windows-forms + - name: WPF + uid: blazor/hybrid/tutorials/wpf - name: Project structure uid: blazor/project-structure - name: Fundamentals