diff --git a/samples/interop/WindowsInteropTest/EmbedToWinFormsDemo.cs b/samples/interop/WindowsInteropTest/EmbedToWinFormsDemo.cs index e6603a817b..d37ed13559 100644 --- a/samples/interop/WindowsInteropTest/EmbedToWinFormsDemo.cs +++ b/samples/interop/WindowsInteropTest/EmbedToWinFormsDemo.cs @@ -1,35 +1,14 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; -using Avalonia.Controls; -using Avalonia.Rendering; -using Avalonia.VisualTree; +using System.Windows.Forms; using ControlCatalog; namespace WindowsInteropTest { public partial class EmbedToWinFormsDemo : Form { - private readonly IRenderer _renderer; - public EmbedToWinFormsDemo() { InitializeComponent(); avaloniaHost.Content = new MainView(); - _renderer = ((TopLevel)avaloniaHost.Content.GetVisualRoot()).Renderer; - _renderer.Start(); - } - - protected override void OnClosed(EventArgs e) - { - _renderer.Stop(); - base.OnClosed(e); } } } diff --git a/src/Windows/Avalonia.Win32.Interoperability/WinForms/WinFormsAvaloniaControlHost.cs b/src/Windows/Avalonia.Win32.Interoperability/WinForms/WinFormsAvaloniaControlHost.cs index 12c8d201a8..9ac00a8b8d 100644 --- a/src/Windows/Avalonia.Win32.Interoperability/WinForms/WinFormsAvaloniaControlHost.cs +++ b/src/Windows/Avalonia.Win32.Interoperability/WinForms/WinFormsAvaloniaControlHost.cs @@ -6,81 +6,110 @@ using Avalonia.Win32.Interop; using WinFormsControl = System.Windows.Forms.Control; using AvControl = Avalonia.Controls.Control; -namespace Avalonia.Win32.Interoperability +namespace Avalonia.Win32.Interoperability; + +/// +/// An element that allows you to host a Avalonia control on a Windows Forms page. +/// +[ToolboxItem(true)] +public class WinFormsAvaloniaControlHost : WinFormsControl { + private AvControl? _content; + private EmbeddableControlRoot? _root; + + private IntPtr WindowHandle => _root?.TryGetPlatformHandle()?.Handle ?? IntPtr.Zero; + /// - /// An element that allows you to host a Avalonia control on a Windows Forms page. + /// Initializes a new instance of the class. /// - [ToolboxItem(true)] - public class WinFormsAvaloniaControlHost : WinFormsControl + public WinFormsAvaloniaControlHost() { - private readonly EmbeddableControlRoot _root = new(); - - private IntPtr WindowHandle => _root?.TryGetPlatformHandle()?.Handle ?? IntPtr.Zero; + SetStyle(ControlStyles.AllPaintingInWmPaint, true); + } - /// - /// Initializes a new instance of the class. - /// - public WinFormsAvaloniaControlHost() + /// + /// Gets or sets the Avalonia control hosted by the element. + /// + public AvControl? Content + { + get => _content; + set { - SetStyle(ControlStyles.AllPaintingInWmPaint, true); - UnmanagedMethods.SetParent(WindowHandle, Handle); - _root.Prepare(); - if (_root.IsFocused) - _root.FocusManager?.ClearFocus(); - _root.GotFocus += RootGotFocus; - - FixPosition(); + if (_content != value) + { + _content = value; + if (_root is not null) + { + _root.Content = value; + } + } } + } - /// - /// Gets or sets the Avalonia control hosted by the element. - /// - public AvControl? Content - { - get => (AvControl?)_root.Content; - set => _root.Content = value; - } + /// + protected override void OnHandleCreated(EventArgs e) + { + _root = new(); + _root.Content = _content; + _root.Prepare(); + _root.Renderer.Start(); + _root.GotFocus += RootGotFocus; - /// - protected override void Dispose(bool disposing) - { - if (disposing) - _root.Dispose(); - base.Dispose(disposing); - } + FixPosition(); + + UnmanagedMethods.SetParent(WindowHandle, Handle); + base.OnHandleCreated(e); + } - private void RootGotFocus(object? sender, Interactivity.RoutedEventArgs e) - { - UnmanagedMethods.SetFocus(WindowHandle); - } + /// + protected override void OnHandleDestroyed(EventArgs e) + { + _root?.Dispose(); + _root = null; + base.OnHandleDestroyed(e); + } - /// - protected override void OnGotFocus(EventArgs e) + /// + protected override void Dispose(bool disposing) + { + if (disposing) { - var handle = WindowHandle; - if (handle != default) - UnmanagedMethods.SetFocus(handle); + _root?.Dispose(); + _root = null; } + base.Dispose(disposing); + } + + private void RootGotFocus(object? sender, Interactivity.RoutedEventArgs e) + { + UnmanagedMethods.SetFocus(WindowHandle); + } + + /// + protected override void OnGotFocus(EventArgs e) + { + var handle = WindowHandle; + if (handle != default) + UnmanagedMethods.SetFocus(handle); + } - private void FixPosition() - { - var handle = WindowHandle; - if (handle != default && Width > 0 && Height > 0) - UnmanagedMethods.MoveWindow(handle, 0, 0, Width, Height, true); - } + private void FixPosition() + { + var handle = WindowHandle; + if (handle != default && Width > 0 && Height > 0) + UnmanagedMethods.MoveWindow(handle, 0, 0, Width, Height, true); + } - /// - protected override void OnResize(EventArgs e) - { - FixPosition(); - base.OnResize(e); - } + /// + protected override void OnResize(EventArgs e) + { + FixPosition(); + base.OnResize(e); + } - /// - protected override void OnPaint(PaintEventArgs e) - { + /// + protected override void OnPaint(PaintEventArgs e) + { - } } }