- •Table of Contents
- •About the Author
- •Acknowledgments
- •Introduction
- •Version Support
- •Supported Versions
- •A Unified Platform
- •Roadmap
- •Supported Operating Systems
- •Command Line Interface
- •Desktop Development
- •Blazor
- •MAUI
- •Wrapping Up
- •.NET 6 Architecture
- •Runtimes
- •CoreCLR
- •Mono
- •WinRT
- •Managed Execution Process
- •Desktop Packs
- •Wrapping Up
- •Dotnet New
- •Dotnet Restore
- •NuGet.config
- •Dotnet Build
- •Dotnet Publish
- •Dotnet Run
- •Dotnet Test
- •Using the CLI in GitHub Actions
- •Other Commands
- •Wrapping Up
- •WinAPI
- •WinForms
- •STAThread
- •WinForms Startup
- •DPI Mode
- •Responding to Scale Events
- •Visual Styles
- •Text Rendering
- •The Message Loop
- •The Form Designer
- •WPF Startup
- •XAML Layout
- •Visual Tree
- •Data Binding
- •Windows App SDK
- •Building a Windows App SDK application
- •Using Windows APIs with Windows App SDK
- •Packaging
- •Migrating to .NET 6
- •Upgrade Assistant
- •Wrapping Up
- •Blazor WebAssembly
- •Creating a Blazor Wasm Project
- •Blazor Progressive Web Apps
- •Exploring the Blazor Client Project
- •Blazor in .NET 6
- •Blazor Component System
- •Creating Blazor Pages
- •Running a Blazor App
- •Blazor Server
- •SignalR
- •Blazor Desktop
- •Wrapping Up
- •Project Structure
- •Exploring MAUI
- •The Cross-Platform World
- •Application Lifecycle
- •MVVM
- •MVVM Toolkit
- •Wrapping Up
- •Model-View-Controller
- •Routing
- •Views
- •Controllers
- •Controller-Based APIs
- •Minimal APIs
- •Wrapping Up
- •Web Apps
- •Creating an App Service
- •Static Web Apps
- •Web App for Containers
- •Docker
- •Azure Functions
- •Deploying Azure Functions
- •Wrapping Up
- •Record Types
- •Monolith Architecture
- •Microservices
- •Container Orchestration
- •Kubernetes
- •Docker Compose
- •Dapr
- •Installing Dapr
- •Dapr State Management
- •Wrapping Up
- •Roslyn
- •Compiler API
- •Diagnostic API
- •Scripting API
- •Workspace API
- •Syntax Tree
- •Roslyn SDK
- •Source Generators
- •Writing a Source Generator
- •Debugging Source Generators
- •Wrapping Up
- •Garbage Collector
- •The Heap
- •The Stack
- •Garbage Collection
- •A Look at the Threadpool
- •Async in .NET 6
- •Await/Async
- •Cancellations
- •WaitAsync
- •Conclusion
- •Index
Chapter 4 Desktop Development
-->
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/ WindowsSettings">true/PM</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/ WindowsSettings">PerMonitorV2, PerMonitor</dpiAwareness>
</windowsSettings>
</application>
</assembly>
Those DPI values sure look familiar; they are the same values we have set back when we were talking about WinForms.
Let’s have a look at MainWindow.xaml. It looks very similar to what we had in WPF, so how do we know we really are using the Windows App SDK with WinUI 3? Figure 4-32 shows what the namespaces for a button in XAML; on the left is the WinUI 3 project we just created, while on the right is a .NET 6 WPF application.
Figure 4-32. WinUI 3 namespaces vs. WPF namespaces
Every control in WinUI 3 lives in the Microsoft.UI.Xaml.Controls namespace. With this, we have confirmation that we are using the controls from the WinUI 3 library, coming from the Windows App SDK NuGet package. No longer do we need to wait for a Windows update whenever a bug is found in a control or when new controls are
announced. Thanks to WinUI 3, the controls are now shipped out of band with Windows, through NuGet.
Using Windows APIs with Windows App SDK
An often-requested feature for WinUI was access to the Windows APIs, for example, to set the title in the window’s title bar or to automatically center a window when launching. This functionality has been released with the Windows App SDK. Listing 4-24
113
Chapter 4 Desktop Development
shows how we can use the Windows App SDK to get a reference to the AppWindow object for the current window. This code can be copied directly in the code behind of any WinUI window, for example, the default MainWindow in the project template.
Listing 4-24. Getting a reference to AppWindow
private AppWindow GetAppWindowForCurrentWindow()
{
IntPtr hWnd = WinRT.Interop.WindowNative.GetWindowHandle(window); WindowId myWndId = Win32Interop.GetWindowIdFromWindow(hWnd); return AppWindow.GetFromWindowId(myWndId);
}
Thanks to the Windows App SDK, we get access to the Windows Runtime, or WinRT, interop capabilities. We first fetch a pointer to where the window lives in memory (window is the name given to the window element in XAML). With that pointer we
can grab the window ID, and finally with that ID we can fetch the actual AppWindow instance.
Now that we have an AppWindow instance we can start using it to manipulate the window. Listing 4-25 shows the code to set a title in the titlebar and to resize the window into a square of 500 by 500 pixels.
Listing 4-25. Manipulating the AppWindow
private void myButton_Click(object sender, RoutedEventArgs e)
{
AppWindow appWindow = GetCurrentAppWindow(); if (appWindow != null)
{
appWindow.Title = "Hello Windows App SDK!"; appWindow.Resize(new SizeInt32(500, 500));
}
}
This code replaces the button’s event handler that was in MainWindow when it was created. When we run this and click the button, you will see the title change, and the window will resize to the result in Figure 4-33.
114
Chapter 4 Desktop Development
Figure 4-33. AppWindow after manipulation
This was just one example of how we can use the Windows App SDK. The full set of documentation can be found at https://docs.microsoft.com/en-us/windows/apps/ windows-app-sdk/ .
Packaging
Once your application is ready to be shipped, we can package it as an MSIX. Make sure to verify the Packaging tab in Package.appxmanifest. Before we can create our MSIX, we need to select a certificate to sign our application. MSIX requires this to prevent attacks on the user’s system through altered software. The toolchain does allow us
to create a test certificate, but I would strongly advice to get a real trusted certificate to sign your applications. For now, for the sake of this demo, a self-signed certificate will suffice. Click on the Choose Certificate option and select Create. This will create a self-signed certificate and add it to your project as a *.pfx file. Figure 4-34 shows the certificate window.
115
Chapter 4 Desktop Development
Figure 4-34. Selecting a certificate for signing
This certificate will now be used to sign your application before packaging it as an MSIX. But certificates only work when they are trusted by the machine they are used on. Navigate to the pfx file in Windows Explorer and double-click it. This will launch the
Certificate Import Wizard. Select Local Machine as store location in step 1. The certificate’s filename in step 2 should already be filled in with your pfx file. In step 3 you are asked to select a password; this is optional and can be left blank. In the final step we will select the certificate store ourselves and browse to Trusted Root Certificate Authorities.
116
Chapter 4 Desktop Development
Figure 4-35. Selected the trusted root authorities
Select Next and Finish to import the certificate into your Trusted Root Authority.
A quick but very important sidenote. We have just imported a self-signed certificate into our Trusted Root store of our machine. This is not the way certificates are meant to be used, and we are potentially opening up our machine for malicious software. Keep this in mind and remove the certificate from your store as soon as possible.
Once everything is in order, right-click the project and select Pack.
117
Chapter 4 Desktop Development
Figure 4-36. Pack option in Visual Studio
Once Visual Studio is done packaging your application, you will find an MSIX file in your project’s bin\<cpu architecture>\Release\net6.0-windows10.0.19041.0\win10-x86\ AppPackages\ApressWinUiDemo_1.0.0.0_x86_Test.
Double-click the MSIX file and an installer will popup. If you did everything correctly, the installer will say that this is a trusted app, which means that the certificate that was used for signing the application is trusted by your machine. Figure 4-37 shows the installer.
Figure 4-37. Installing an MSIX packaged application
After installing, the application will show up in the list of installed applications on your Windows installation. Remember, this application is using sandboxed registry and filesystem, so uninstalling it shouldn’t leave a trace behind.
118
