This playbook provides a practical sequencing model for migrating production WinForms applications to Avalonia with minimal regression risk.
Dock/Anchor, migrate data binding to typed view models.x:DataType) for migrated views.WinForms baseline (slice candidate):
var toolbar = new FlowLayoutPanel
{
Dock = DockStyle.Top,
AutoSize = true
};
var searchBox = new TextBox { Width = 220 };
var exportButton = new Button { Text = "Export" };
var customersGrid = new DataGridView
{
Dock = DockStyle.Fill,
AutoGenerateColumns = false
};
exportButton.Click += (_, _) => ExportVisibleCustomers();
searchBox.TextChanged += (_, _) => ApplyFilter(searchBox.Text);
toolbar.Controls.Add(searchBox);
toolbar.Controls.Add(exportButton);
Controls.Add(customersGrid);
Controls.Add(toolbar);
Avalonia XAML target slice:
<Grid xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:MyApp.ViewModels"
x:DataType="vm:CustomerSearchViewModel"
RowDefinitions="Auto,*"
RowSpacing="8">
<StackPanel Orientation="Horizontal" Spacing="8">
<TextBox Watermark="Search" Text="{CompiledBinding Query, Mode=TwoWay}" />
<Button Content="Export" Command="{CompiledBinding ExportCommand}" />
</StackPanel>
<ListBox Grid.Row="1" ItemsSource="{CompiledBinding FilteredCustomers}" />
</Grid>
public sealed class MigrationSlice
{
public string Name { get; init; } = string.Empty;
public bool LayoutPorted { get; set; }
public bool BindingPorted { get; set; }
public bool CommandsPorted { get; set; }
public bool DialogsPorted { get; set; }
public bool Verified { get; set; }
}
public static bool ReadyForCutover(MigrationSlice slice)
=> slice.LayoutPorted && slice.BindingPorted && slice.CommandsPorted && slice.DialogsPorted && slice.Verified;