What makes a program a Windows program is that it behaves the way people are used to from Windows: the window is where it was the last time at the next start. The title bar fits the user interface. You choose a file in the familiar dialog. A second click on the icon brings the first window to the front instead of starting a second program. And a reminder appears at the edge of the screen, even when another window is on top.
This lesson builds these five things into the Kladde. It keeps the rule from lesson 0201: whatever contains rules lives in Kladde.Desktop.Logic and has xUnit tests; whatever calls the Windows App SDK stays thin in Kladde.Desktop. Adapt the names to your projects. The lesson assumes the pages and view models of lessons 0101 through 0202.
State of the checks. Everything that calls the Windows App SDK (window, title bar, pickers, activation, notification, manifest) comes from Microsoft Learn and its samples and was not run: when this was written, no Windows machine with WinUI tools was available, and no window and no notification was seen. Built and tested in a throwaway project with .NET 10 and xUnit were the pure classes of the lesson (
WindowPlacementRules,WindowPlacementJson,ReminderPlanner,AppointmentCsv) with their tests. Where a source leaves something open, the text says open. Compare every passage with the linked page and play through the exercises on a Windows machine.
Window and AppWindow
A window has two faces. You create Microsoft.UI.Xaml.Window with new MainWindow(); the content and the commands Activate() and Close() hang on it. Microsoft.UI.Windowing.AppWindow belongs to the Windows App SDK and manages what hangs on the window itself: size, position, title bar, icon and the presentation (normal, full screen, small floating window). Both describe the same Win32 window, the HWND; Learn calls it a one-to-one mapping. You get the AppWindow from the Window:
AppWindow appWindow = this.AppWindow; // in MainWindow.xaml.cs
From a Page you do not have the Window. The Kladde keeps it in a static property (public static MainWindow? MainWindowInstance { get; private set; } in App).
Member of AppWindow |
Purpose |
|---|---|
Position, Size |
position and size of the whole window, read only |
Move, Resize, MoveAndResize |
set them, in physical pixels |
Changed |
one event for all changes (DidPositionChange, DidSizeChange, DidPresenterChange) |
Presenter |
OverlappedPresenter (default), FullScreenPresenter, CompactOverlayPresenter |
The physical pixels are the trap: WinUI calculates in logical pixels, which grow with the scaling; a value from AppWindow.Size at 150 percent is one and a half times as large as what you see in XAML. Learn calls size settings in logical pixels on the Window experimental; the course does not use them.