Peter Dannenberg

WinForms Meets WPF: The Hybrid Path to Modern Desktop Applications

Rewriting a massive WinForms app is often impossible. Discover a pragmatic hybrid path that hosts legacy screens inside a new WPF application, migrating one piece at a time.

WinForms Meets WPF: The Hybrid Path to Modern Desktop Applications
#1about 3 minutes

The case for modernizing WinForms applications

Legacy WinForms applications face challenges with modern UI/UX expectations and finding developers, making modernization a critical consideration.

#2about 3 minutes

Choosing between a full rewrite and a hybrid migration

A hybrid approach is often more practical than a complete rewrite for large, complex applications, but it is not suitable for performance-critical software.

#3about 1 minute

Understanding the pitfalls of hybrid applications

Hybrid WinForms and WPF applications present challenges like the airspace problem and differing threading models that require careful management.

#4about 2 minutes

Implementing a shell strategy with WindowsFormsHost

The hybrid migration uses a WPF shell to host WinForms content, requiring a custom WindowsFormsHost to support MDI windows.

#5about 3 minutes

A tour of the legacy WinForms application

The starting point for the migration is a typical MDI-based WinForms application that includes third-party controls and modal dialogs.

#6about 3 minutes

Building the new WPF shell application

The new WPF application is built to act as a modern shell, utilizing dependency injection and a dashboard for launching application features.

#7about 3 minutes

How WindowsFormsHost bridges WPF and WinForms

The WindowsFormsHost acts as a "black hole" in the WPF layout by parenting a native WinForms window handle (HWND) and requires separate STA threads for each UI stack.

#8about 1 minute

Avoiding memory leaks and duplicate dispose calls

Proper window destruction is critical in hybrid apps to prevent memory leaks, which involves carefully managing Dispose calls to avoid duplicates.

#9about 4 minutes

Implementing a custom WindowsFormsHost class

A custom WindowsFormsHost is created by inheriting from HWNDHost and implementing the core logic to build and parent the WinForms window handle.

#10about 2 minutes

Using an interop manager to simplify window hosting

An InteropManager class centralizes the logic for creating hosted windows and synchronizing properties like size, title, and border style from WinForms to WPF.

#11about 3 minutes

Decoupling applications with services and connectors

A dedicated connector project with callbacks and services acts as a bridge, allowing the WPF and WinForms applications to communicate without direct dependencies.

#12about 2 minutes

Hosting the entire WinForms MDI app in WPF

The complete legacy WinForms MDI application can be hosted inside the new WPF shell, preserving all its original functionality including third-party controls.

#13about 2 minutes

Migrating screen-by-screen using MDI windows

The MDI architecture enables a gradual migration by allowing individual child windows to be opened directly within the WPF shell, facilitating a step-by-step replacement.

#14about 2 minutes

Resolving keyboard input inconsistencies

Differences in keyboard behavior, such as tab navigation, can be resolved by implementing the IKeyboardInputSink interface within the custom WindowsFormsHost.

#15about 4 minutes

Fixing WinForms dialogs with a message loop

Hosted WinForms dialogs fail to close because the message loop is not processed, a problem solved by implementing a custom loop in the WindowsFormsHost to detect the close event.

#16about 1 minute

Conclusion and where to find the source code

The hybrid approach offers a viable path for modernizing large WinForms applications, and the complete source code for this demo is available on GitHub.

Related jobs
Jobs that call for the skills explored in this talk.

Featured Partners

Related Articles

View all articles

From learning to earning

Jobs that call for the skills explored in this talk.