Skip to main content Skip to footer

WinUI Tips & Tricks for WinForms Developers

WinUI is the latest .NET technology for developing Windows desktop applications. Many developers are familiar with Windows Forms, but they may wonder how difficult it will be to migrate their desktop applications to WinUI.

WinUI can feel familiar and surprisingly different coming from Windows Forms. In this article, we cover five tips for WinForms developers to better understand how WinUI development differs. We explore:

Ready to get started? Download ComponentOne Today!

Data Binding & MVVM

With WinUI development, you should think in terms of data binding with MVVM rather than code-behind logic.

WinUI is very similar to WPF in that it uses XAML markup to define the UI and supports object-based data binding to a data context. This architecture gives us what we commonly refer to as "MVVM" (Model-View-ViewModel).

  • The XAML UI is the View bound to properties on the ViewModel
  • The ViewModel is a C# class that can manipulate the data
  • The Model represents the business data classes

Data binding is easily one of the best advantages of XAML-based platforms like WinUI.

With WinForms, you would typically write UI logic in the code-behind. This results in disorganized code that can't be easily tested or reused. When the UI logic lives in event handlers, controls are manipulated directly, and your forms end up providing the business logic throughout your entire application. You can abstract classes and methods to organize it better, but the MVVM approach is essentially the result you're trying to achieve, and WinUI makes it easy.

These code snippets give a general view of the MVVM data binding:

<!- XAML View ->
<TextBox Text={Binding MyValue} />

// C# ViewModel
public double MyValue { get; set; }

MVVM Diagram

For more on MVVM, you can check out our webinar on WPF Application Development, which coincides with WinUI app development in many ways.

Adaptive and Resolution Independent Layouts

With WinUI, the user interface layout is declarative, adaptive, and not just pixel-based.

WinForms UIs are built using absolute positioning, which makes the WYSIWYG designer almost essential. While the designer simplifies layout, adaptive and resolution-independent interfaces aren't automatic. Third-party tools like ComponentOne Sizer can help, but DPI scaling in WinForms can still be challenging.

WinUI, like WPF, uses container-driven XAML, a declarative markup language similar to HTML. Layouts are easier to understand directly from the markup, and many developers prefer writing XAML by hand rather than relying on a designer (WinUI currently does not offer a full WYSIWYG designer).

With XAML, creating DPI-aware and scalable UIs is straightforward. By using core layout controls such as Grid, StackPanel, and ScrollViewer, you describe relationships rather than fixed positions, which makes adaptive design a natural part of the development process.

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
</Grid>

Reusable and Encapsulated Styling

With WinUI, styling is highly centralized and reusable, making it easy to use, scalable, and efficient to maintain.

In WinForms, styling is per control, and style customization often requires creating subclassing controls or creating custom renderers that paint each pixel. WinUI (like WPF) uses Styles, Templates, and Resources, which are easy to define and highly reusable.

  • Templates help define custom parts of the UI, such as datagrid row template.
  • Styles encapsulate properties into a single reusable element that can apply a consistent configuration across the entire application.
  • Resources are reusable elements, which can include Styles, Templates, Colors, Brushes, Images, etc.

Keep in mind that Styles are not just for colors and borders; they can also be used to encapsulate any property. They ensure consistent styling across your entire application. This Style below defines all buttons to have rounded corners with specific padding.

<Style TargetType="Button">
    <Setter Property="CornerRadius" Value="6"/>
    <Setter Property="Padding" Value="12,6"/>
</Style>

Additionally, WinUI uses a clean, modern, "fluent" style by default, whereas WinForms has an outdated gray look and feel that most users associate with older software. Through custom themes, we can achieve a modern look in WinForms, such as with ComponentOne Themes, but WinUI has the advantage of not requiring extra work to achieve a modern style.

Clean Asynchronous Workflows Replace Threading

With Windows Forms, you have more control over the message loop. Everything runs on a single UI thread, and you have to use things like Control.Invoke to execute code from a different thread. While this gives you more control, it can lead to more difficulties and errors.

With WinUI, this threading is abstracted away, and that's a good thing! The framework manages the windowing model, message dispatching, and threading infrastructure for you. The new approach to threading is the async/wait responsive workflows. The result is that you end up spending less time struggling with threading (our absolute least favorite thing about coding) and more time writing naturally, clean, structured, asynchronous code and letting WinUI handle the orchestration.

Below is a simple WinUI-style async/await workflow code snippet that replaces the old background thread + Control.Invoke pattern from WinForms.

private async void LoadButton_Click(object sender, RoutedEventArgs e)
{
     StatusText = "Loading...";
     // Asynchronous file read (does NOT block UI thread)
     string contents = await File.ReadAllTextAsync(@"C:\Temp\data.txt");
     // After await, execution resumes on the UI thread automatically
     StatusText = "Done";
     FileContents = contents;
}

How to Access Files from a Sandbox

File access between WinForms and WinUI is identical whether you are developing a packaged or unpackaged WinUI app for the desktop. Instead of using the OpenFileDialog, you would use the asynchronous and window-aware FileOpenPicker class.

The major difference with WinUI file access applies to MSIX-packaged apps. These apps operate in a sandbox, which means you only have free access to files within your app's installation folder. Plus, you can access outside files only through a FileOpenPicker, which lets the user fully control how your app can access their files. WinUI has been designed to develop safer applications from the user's perspective, which means developers have to work around these limitations to ensure the safety of the user's machine.

File access tips:

  • If your app requires extensive file access, you should build an unpackaged WinUI app for the desktop.
  • If you must build an MSIX-packaged app, design your app's file access through the FileOpenPicker dialog or use local files to your app's installation folder.

A quick example of how to create a local file in the local application folder is shown below:

var local = ApplicationData.Current.LocalFolder;
var file = await local.CreateFileAsync("settings.json");

WinUI Tips for WinForms Developers

These tips have focused on what's conceptually new and what's most valuable to internalize early. For Windows Forms developers, many fundamentals still apply, but the way you think about things should shift. WinUI encourages you to think in terms of data binding rather than direct control manipulation, composition rather than inheritance, async workflows rather than manual thread marshaling, and adaptive layouts rather than pixel positioning. You no longer manage the message loop or constantly guard against cross-thread UI access. WinUI itself and modern async patterns handle much of that complexity for you.

Regardless of whether you develop with WinForms or WinUI, ComponentOne includes powerful UI controls for building desktop Enterprise Apps.

Ready to check it out? Download ComponentOne Today!

comments powered by Disqus