question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Hosting Avalonia User Controls in Windows Forms on DotNet 7+

See original GitHub issue

Is your feature request related to a problem? Please describe.

There is a need to gradually migrate some of our WinForms apps to Avalonia. To that end, we need to slowly, piece-by-piece replace WinForms user controls with Avalonia alternatives, eventually replacing the whole main window with one based on Avalonia. This approach requires us to be able to host Avalonia controls within WInForms Forms / UserControls.

So, I was trying to figure out a way to do it. The reverse (hosting WinForms control inside of Avalonia app) seems pretty straight forward. Not so however with the other way around. I stumbled across Avalonia.Win32.Interoperability nuget package, however it was for an older Avalonia version and more crucially seemed to be targeting .Net Framework (as opposed to DotNet 7+). Researching a bit more I came across: WinFormsAvaloniaControlHost from that same package.

So, I tried using it directly in my DotNet7 project. It was pretty easy to port. However there were 2 remaining issues:

  • private IntPtr WindowHandle => ((WindowImpl) _root?.PlatformImpl)?.Handle?.Handle ?? IntPtr.Zero; could not be ported because apparently recently WindowImpl was made internal, nor was there a public interface on it that exposes the needed IPlatformHandle Handle propety.
  • EmbeddableControlRoot.FocusManager was not there which I needed to port if (_root.IsFocused) _root.FocusManager.ClearFocus();, though this seemed less important.

I resolved the first issue with an ugly reflection hack, basically gaining access to ((WindowImpl) _root?.PlatformImpl)?.Handle?.Handle through reflection, which for the purposes of testing sufficed.

So then I proceeded with a simple code to host my Avalonia control inside of WinForms:


  public Form1() {
    InitializeComponent();
    var avahost = new WinFormsAvaloniaControlHost(); // <-- Implemented in my project as I ported it from https://github.com/AvaloniaUI/Avalonia/blob/master/src/Windows/Avalonia.Win32.Interop/WinForms/WinFormsAvaloniaControlHost.cs
    panel1.Controls.Add(avahost);
    avahost.Dock = DockStyle.Fill;
    avahost.Content = new UserControl1();
  }

However once I ran my program, I would always be getting a pure white background in place where my Avalonia control should be.

Describe the solution you’d like Basically I should just be able to host Avalonia control within any WinForms Form or User Control, so that we can migrate large WinForms app slowly over time, and this scenario is important not just for .Net Framework, but for modern DotNet (i.e. 7+)

  • As an aside, for such scenarios it is especially important to be able to access Avalonia control’s native handles (when they exist), such that there is no need to use Reflection hacks. These handles should be part of a public surface APIs.
  • Also how should Avalonia be properly initialized for such a scenario (i.e. where the main program / app is WInForms). Do we just use BuildAvaloniaApp().SetupWithoutStarting(); in our porogram main before we do System.Windows.Forms.Application.Run(new Form1());, or do we do something else?

Describe alternatives you’ve considered There are really no feasible alternatives. Hosting WinForms inside Avalonia - doing it the other way around in other words is not really possible since the whole form would somehow need to be hosted inside of Avalonia. Not to mention there will still be a need to host Avalonia controls inside of WinForms container controls (until the entire UI was migrated to Avalonia).

Additional context Using DotNet 7+ in VS 2022.

Issue Analytics

  • State:closed
  • Created 4 months ago
  • Comments:19 (15 by maintainers)

github_iconTop GitHub Comments

1reaction
maxkatz6commented, May 23, 2023

@fitdev thanks! I will do the rest with updating interop package and making it publish to the nuget again.

1reaction
profix898commented, May 22, 2023

@fitdev: Doesnt work that easily 😉 PlatformImpl on TopLevel is an ITopLevelImpl, which itself does not contain the handle. Only IWindowBaseImpl contains the required handle, so the minimum would be to do public IPlatformHandle? TryGetPlatformHandle() => ((IWindowBaseImpl?) PlatformImpl)?.Handle; (trying to get PlatformImplas a IWindowBaseImpl).

Read more comments on GitHub >

github_iconTop Results From Across the Web

Has anyone gotten Avalonia Host Control to work in ...
The use case is we have a windows forms app, and we want to update the UI to Avalonia. Since it can't all...
Read more >
UserControls
UserControl represents a "view" in Avalonia, which is a reusable collection of controls in a predefined layout.
Read more >
Embedding Native (Windows and Linux) Views/Controls ...
This article describes embedding native Windows and Linux control into an Avalonia application.
Read more >
Host a WPF composite control in Windows Forms
The Windows Forms host application uses an ElementHost object to host the WPF composite control. The application handles the OnButtonClick event ...
Read more >
Avalonia Ui putting a UserControl inside another
In this code, I need to put a menu on another UserControl, but the Menu is in a different UserControl (however, it could...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found