Post

Dealing with application windows on Windows with .NET MAUI

As we have done the work for macOS, we can turn our attention now to the Windows operating system. Spoiler: this post will be far shorter than the last one.

Recap

Dealing with application windows on macOS with .NET MAUI

In my last post, I showed you how to support multiple windows and handle their size. I introduced you the IWindowService to handle windows in an MVVM friendly way and told you some gotchas on macOS.

Let’s dive into the Windows implementation.

Supporting multiple application windows

WinUI, the underlying technology for Windows apps with MAUI, supports multiple application windows by default. There is no additional setup necessary.

To determine between the main application window and secondary ones, we still keep the PrimaryWindow and the SecondaryWindow classes around.

Window Sizing

We are lucky again. Both the way of setting the fixed size and also dynamic sizes work also on Windows. The only difference here is that we could also resize the window manually by setting just the height and width of it. To keep the API constant, we are going to reuse the MacCatalyst implementation, however.

So once again, we can rush ahead to the next step and take a look into the MVVM part of the whole setup.

Handling application windows with MVVM

Let’s try to remember the components of my implementation:

  • Windows resizing page base class
  • Secondary window base page class and its base ViewModel
  • our PrimaryWindow and SecondaryWindow
  • last but not least, the IWindowService

ResizeableDesktopBasePage

Named ResizeableMacBasePage before, the implementation created in the last post is working fine with WinUI, so I renamed it to ResizableDesktopBasePage. That’s all I changed, the rest of the code is still the same.

The secondary window base page now derives from the newly named class, that’s all we need to change for now. This means we can fast-forward to the IWindowService!

IWindowService

Well, I know this gets boring, but once again, we do not need to change anything. Just use the IWindowService in the same way as already outlined in my last post.

There is one difference in the whole construct, however.

Sizing the main window after restart

Unlike macOS, the Windows OS does not choose the best size for our main application window once it got resized. It just goes with the default window size, except if we tell it to use another one.

Because of this behavior, we can resize the main application window when the application is starting. To achieve this goal, I added a little helper method in App.xaml.cs:

1
2
3
4
5
6
7
8
9
 private void TryToSizeAsOnLastRun(PrimaryWindow window)
{
    var lastknownMainWindowHeight = Preferences.Default.Get(Constants.SettingsLastKnownPrimaryWindowHeight, double.PositiveInfinity);
    var lastknwonMainWindowWidth =
        Preferences.Default.Get(Constants.SettingsLastKnownPrimaryWindowWidth, double.PositiveInfinity);

    window.Height = lastknownMainWindowHeight;
    window.Width = lastknwonMainWindowWidth;
}

Once we have created the PrimaryWindow instance in the CreateWindow method, we call this method and our Window will be sized correctly once the main window starts up.

Conclusion

As we did the “hard” work already when we wrote the MacCatalyst implementation, we went pretty fast through the WinUI implementation. We took advantage of the MAUI framework that allows us to handle the application windows in a common way. This blog post is a more documentary one, but I still hope it is helpful for some of you.

You can find the updated sample here on GitHub.

Until the next post, happy coding, everyone!

This post is licensed under CC BY 4.0 by the author.

Comments powered by Disqus.