浏览代码

Start WF control render timer when handle is created and stop when handle is destroyed

Max Katz 2 年之前
父节点
当前提交
f31b42d901

+ 1 - 22
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);
         }
     }
 }

+ 88 - 59
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;
+
+/// <summary>
+/// An element that allows you to host a Avalonia control on a Windows Forms page.
+/// </summary>
+[ToolboxItem(true)]
+public class WinFormsAvaloniaControlHost : WinFormsControl
 {
+    private AvControl? _content;
+    private EmbeddableControlRoot? _root;
+
+    private IntPtr WindowHandle => _root?.TryGetPlatformHandle()?.Handle ?? IntPtr.Zero;
+
     /// <summary>
-    /// An element that allows you to host a Avalonia control on a Windows Forms page.
+    /// Initializes a new instance of the <see cref="WinFormsAvaloniaControlHost"/> class.
     /// </summary>
-    [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);
+    }
 
-        /// <summary>
-        /// Initializes a new instance of the <see cref="WinFormsAvaloniaControlHost"/> class.
-        /// </summary>
-        public WinFormsAvaloniaControlHost()
+    /// <summary>
+    /// Gets or sets the Avalonia control hosted by the <see cref="WinFormsAvaloniaControlHost"/> element.
+    /// </summary>
+    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;
+                }
+            }
         }
+    }
 
-        /// <summary>
-        /// Gets or sets the Avalonia control hosted by the <see cref="WinFormsAvaloniaControlHost"/> element.
-        /// </summary>
-        public AvControl? Content
-        {
-            get => (AvControl?)_root.Content;
-            set => _root.Content = value;
-        }
+    /// <inheritdoc />
+    protected override void OnHandleCreated(EventArgs e)
+    {
+        _root = new();
+        _root.Content = _content;
+        _root.Prepare();
+        _root.Renderer.Start();
+        _root.GotFocus += RootGotFocus;
 
-        /// <inheritdoc />
-        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);
-        }
+    /// <inheritdoc />
+    protected override void OnHandleDestroyed(EventArgs e)
+    {
+        _root?.Dispose();
+        _root = null;
+        base.OnHandleDestroyed(e);
+    }
 
-        /// <inheritdoc />
-        protected override void OnGotFocus(EventArgs e)
+    /// <inheritdoc />
+    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);
+    }
+
+    /// <inheritdoc />
+    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);
+    }
         
-        /// <inheritdoc />
-        protected override void OnResize(EventArgs e)
-        {
-            FixPosition();
-            base.OnResize(e);
-        }
+    /// <inheritdoc />
+    protected override void OnResize(EventArgs e)
+    {
+        FixPosition();
+        base.OnResize(e);
+    }
 
-        /// <inheritdoc />
-        protected override void OnPaint(PaintEventArgs e)
-        {
+    /// <inheritdoc />
+    protected override void OnPaint(PaintEventArgs e)
+    {
 
-        }
     }
 }