Migrating from WinForms to WPF, WinUI or Blazor Hybrid

Inventory a legacy codebase, separate business logic from UI, migrate incrementally with interop, and compare the replacement stacks honestly.

Inventory before you rewrite

A WinForms application hides its business rules in event handlers. The first job is to find out how much of the code is genuinely about orders and how much is about pixels - the ratio decides whether a migration is worth doing at all.

  1. List every form and count the lines in code-behind. Forms over a few hundred lines of logic are the ones to attack first.
  2. Mark every place the UI touches the database, the network or the file system directly. Those are the seams where a service layer should go.
  3. Find the controls with no modern equivalent or with different behaviour: DataGridView, PropertyGrid, third-party gauges.
  4. Write a smoke test that exercises the core workflow with no UI at all. If you cannot, the logic is still trapped and extraction comes first.
  5. Count the third-party control licences - replacing a grid is often the largest single line of a migration budget.
// before: the rule lives in the click handler
private void OnApprove(object sender, EventArgs e)
{
    if (orderGrid.CurrentRow?.DataBoundItem is Order o && o.Total < 500)
    {
        o.Status = "Approved";
        _repo.Save(o);
        orderGrid.Refresh();
    }
}

// after: the rule is testable and the UI only calls it
public sealed class OrderService
{
    public Result Approve(Order order)
    {
        if (order.Total >= 500m)
            return Result.Fail("Orders over 500 need a second approver.");
        order.Status = OrderStatus.Approved;
        _repo.Save(order);
        return Result.Ok();
    }
}

private void OnApprove(object sender, EventArgs e)
{
    if (orderGrid.CurrentRow?.DataBoundItem is not Order o) return;
    var result = _service.Approve(o);
    if (!result.Succeeded) errors.SetError(approveButton, result.Message);
}

Choosing the target

StackStrengthsCostsPick it when
WPFMature, deep control ecosystem, XAML, MVVMLearning curve for binding and templatesA long-lived desktop app on .NET
WinUI 3Modern controls, fluent design, Windows App SDKEcosystem still smaller than WPF'sA new Windows-only app with a modern look
Blazor HybridWeb UI skills, one component model, MAUI hostWebView overhead; heavy data grids stay hardYour team is strongest in web technologies
MAUIOne codebase across desktop and mobileDesktop fidelity gaps; churn in the toolingYou also need mobile from the same code
Stay on WinFormsZero migration cost, everything already worksDated UI, no dark mode story, weaker testabilityThe app is stable and rarely touched

A rewrite is justified by a business driver - new platforms, a new design language, hiring difficulty - not by the age of the framework. A stable internal tool that works is not a problem to be solved.

Migrating incrementally

// host a WinForms control inside a WPF window while you migrate screen by screen
public partial class LegacyHost : System.Windows.Forms.Integration.WindowsFormsHost
{
    public LegacyHost()
    {
        Child = new OrderGridControl();       // the untouched WinForms control
    }
}

// and the reverse: a WPF control inside a WinForms form, via element host
var host = new ElementHost { Dock = DockStyle.Fill, Child = new WpfSummaryView() };
panel.Controls.Add(host);
  • Migrate screen by screen behind a shell that can host both, so the application stays shippable at every step.
  • Mixing WindowsFormsHost and ElementHost has airspace and DPI limitations: a hosted control always renders on top, and per-monitor scaling needs both stacks to agree.
  • Move the business logic first, the UI second. Logic extracted with no test coverage will be rewritten twice.
  • Freeze new features on the old screens. Two live UI styles in one product is a temporary state with a deadline, not a destination.
⚠️
Do not start a migration without an end date for the parallel period. Interop layers are easy to add and very hard to remove: two years later you will have two UI stacks, two theming systems and a maintenance bill for both.

FAQ

Can I convert XAML back to WinForms?
No, and there is no automated WinForms-to-XAML converter worth the risk. The designer files are a serialised object graph; a mechanical translation produces XAML that compiles and looks wrong.
Is WinForms dead?
No. It is still supported on current .NET and receives fixes and dark-mode support. It is simply no longer the recommended choice for new applications that need a modern UI.

Deployment: ClickOnce, MSIX and single-file Forms and controls

Last refreshed 2026-09-18.