RoyalApps.Community.Avalonia.Windows 1.0.1

Prefix Reserved
There is a newer version of this package available.
See the version list below for details.
dotnet add package RoyalApps.Community.Avalonia.Windows --version 1.0.1                
NuGet\Install-Package RoyalApps.Community.Avalonia.Windows -Version 1.0.1                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="RoyalApps.Community.Avalonia.Windows" Version="1.0.1" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add RoyalApps.Community.Avalonia.Windows --version 1.0.1                
#r "nuget: RoyalApps.Community.Avalonia.Windows, 1.0.1"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install RoyalApps.Community.Avalonia.Windows as a Cake Addin
#addin nuget:?package=RoyalApps.Community.Avalonia.Windows&version=1.0.1

// Install RoyalApps.Community.Avalonia.Windows as a Cake Tool
#tool nuget:?package=RoyalApps.Community.Avalonia.Windows&version=1.0.1                

Utilities and Helpers for AvaloniaUI

NuGet Version NuGet Downloads .NET

RoyalApps.Community.Avalonia

RoyalApps.Community.Avalonia contains projects/packages for AvaloniaUI.

RoyalApps.Community.Avalonia.Windows

This package contains a WinFormsControlHost with a custom lifecycle management. XAML based controls like the TabControl in Avalonia, detach and attach views dynamically when switching between tabs. In general, this is a good approach to make rendering and resource utilization efficient.

Putting a NativeControlHost in such a view can cause issues because every time the view gets detached and another one attached, the native control is destroyed and recreated. If you want to host legacy WinForms controls, for example, you might want to have more control over the lifetime of your user control.

InteropDemo

The demo application as shown above, creates a view with a WinFormsControlHost for each tab. The WinForms control (also part of the demo app), simply contains a text box, prints an "instance id" and has a random background color to demonstrate that the instances "survive" and keep the state until manually disposed.

Installation

Install the RoyalApps.Community.Avalonia.Windows with NuGet:

Install-Package RoyalApps.Community.Avalonia.Windows

or via the command line interface:

dotnet add package RoyalApps.Community.Avalonia.Windows

Using the WinFormsNativeHost Control

Add the Control

You can find the WinFormsControlHost in the namespace RoyalApps.Community.Avalonia.Windows.NativeControls:

<UserControl xmlns="https://github.com/avaloniaui"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:winForms="clr-namespace:InteropDemo.WinForms;assembly=InteropDemo.WinForms"
             xmlns:nativeControls="clr-namespace:RoyalApps.Community.Avalonia.Windows.NativeControls;assembly=RoyalApps.Community.Avalonia.Windows"
             mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
             x:Class="InteropDemo.Views.TestView"
             Padding="10">
    <nativeControls:WinFormsControlHost x:Name="WinFormsControlHost" x:TypeArguments="winForms:TestControl" />
</UserControl>

Note
Since the control is a generic type WinFormsControlHost<T> where T : System.Windows.Forms.Control, you need to specify the type of your WinForms control you want to host in the x:TypeArguments attribute.

By default, the WinFormsControlHost<T> creates a new instance of your type automatically and keeps track of the instance. You can subclass the control and override the OnCreateWinFormsControl() method to create and return the instance of the WinForms control yourself.

To configure your control (e.g. set properties), use the OnLoaded() override:

protected override void OnLoaded()
{
    base.OnLoaded();

    if (WinFormsControlHost.Control is not { } testControl)
        return;
    testControl.BackColor = Color.White;
}
Manage the Lifetime of the Control

In the view model you use as data context where you placed the WinFormsControlHost, simply implement the IDisposeWinFormsControl interface:

public partial class TabViewModel : ViewModelBase, IDisposeWinFormsControl
{
    [ObservableProperty] private string _caption = "n/a";

    public event EventHandler<WinFormsDisposeEventArgs>? DisposeWinFormsControl;

    [RelayCommand] public void Close() => App.MainViewModel.RemoveTab(this);

    public void RaiseTabClosing()
    {
        DisposeWinFormsControl?.Invoke(this, new WinFormsDisposeEventArgs(this));
    }
}

Simply invoke the DisposeWinFormsControl event and pass the instance of the view model to the WinFormsDisposeEventArgs constructor.

How does it work?

The singleton class WinFormsLifetimeManager keeps the instances of all WinForms controls in a dictionary as long as they are required (not manually disposed).

Note
The view model instance (which implements IDisposeWinFormsControl) will be used as key for the dictionary. Depending on your view model implementation, you might see issues with this approach when GetHashcode or Equals is overridden.

The WinFormsControlHost inherits from NativeControlHost and prevents the control from being destroyed. When an instance of the WinForms control is requested for a specific view model, you either get an existing instance if available, or an instance is created for you.

When you are done (e.g. the view model is getting removed for good), you invoke the DisposeWinFormsControl event on your view model to signal the WinFormsLifetimeManager the WinForms control can be destroyed/disposed.

Product Compatible and additional computed target framework versions.
.NET net7.0-windows7.0 is compatible.  net8.0-windows was computed.  net9.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net7.0-windows7.0

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.2.0 65 1/8/2025
1.0.3 137 6/22/2023
1.0.1 98 6/22/2023