Browse Source

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

pull/11488/head
Max Katz 3 years ago
parent
commit
f31b42d901
  1. 23
      samples/interop/WindowsInteropTest/EmbedToWinFormsDemo.cs
  2. 147
      src/Windows/Avalonia.Win32.Interoperability/WinForms/WinFormsAvaloniaControlHost.cs

23
samples/interop/WindowsInteropTest/EmbedToWinFormsDemo.cs

@ -1,35 +1,14 @@
using System; using System.Windows.Forms;
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 ControlCatalog; using ControlCatalog;
namespace WindowsInteropTest namespace WindowsInteropTest
{ {
public partial class EmbedToWinFormsDemo : Form public partial class EmbedToWinFormsDemo : Form
{ {
private readonly IRenderer _renderer;
public EmbedToWinFormsDemo() public EmbedToWinFormsDemo()
{ {
InitializeComponent(); InitializeComponent();
avaloniaHost.Content = new MainView(); avaloniaHost.Content = new MainView();
_renderer = ((TopLevel)avaloniaHost.Content.GetVisualRoot()).Renderer;
_renderer.Start();
}
protected override void OnClosed(EventArgs e)
{
_renderer.Stop();
base.OnClosed(e);
} }
} }
} }

147
src/Windows/Avalonia.Win32.Interoperability/WinForms/WinFormsAvaloniaControlHost.cs

@ -6,81 +6,110 @@ using Avalonia.Win32.Interop;
using WinFormsControl = System.Windows.Forms.Control; using WinFormsControl = System.Windows.Forms.Control;
using AvControl = Avalonia.Controls.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> /// <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> /// </summary>
[ToolboxItem(true)] public WinFormsAvaloniaControlHost()
public class WinFormsAvaloniaControlHost : WinFormsControl
{ {
private readonly EmbeddableControlRoot _root = new(); SetStyle(ControlStyles.AllPaintingInWmPaint, true);
}
private IntPtr WindowHandle => _root?.TryGetPlatformHandle()?.Handle ?? IntPtr.Zero;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="WinFormsAvaloniaControlHost"/> class. /// Gets or sets the Avalonia control hosted by the <see cref="WinFormsAvaloniaControlHost"/> element.
/// </summary> /// </summary>
public WinFormsAvaloniaControlHost() public AvControl? Content
{
get => _content;
set
{ {
SetStyle(ControlStyles.AllPaintingInWmPaint, true); if (_content != value)
UnmanagedMethods.SetParent(WindowHandle, Handle); {
_root.Prepare(); _content = value;
if (_root.IsFocused) if (_root is not null)
_root.FocusManager?.ClearFocus(); {
_root.GotFocus += RootGotFocus; _root.Content = value;
}
FixPosition(); }
} }
}
/// <summary> /// <inheritdoc />
/// Gets or sets the Avalonia control hosted by the <see cref="WinFormsAvaloniaControlHost"/> element. protected override void OnHandleCreated(EventArgs e)
/// </summary> {
public AvControl? Content _root = new();
{ _root.Content = _content;
get => (AvControl?)_root.Content; _root.Prepare();
set => _root.Content = value; _root.Renderer.Start();
} _root.GotFocus += RootGotFocus;
/// <inheritdoc /> FixPosition();
protected override void Dispose(bool disposing)
{ UnmanagedMethods.SetParent(WindowHandle, Handle);
if (disposing) base.OnHandleCreated(e);
_root.Dispose(); }
base.Dispose(disposing);
}
private void RootGotFocus(object? sender, Interactivity.RoutedEventArgs e) /// <inheritdoc />
{ protected override void OnHandleDestroyed(EventArgs e)
UnmanagedMethods.SetFocus(WindowHandle); {
} _root?.Dispose();
_root = null;
base.OnHandleDestroyed(e);
}
/// <inheritdoc /> /// <inheritdoc />
protected override void OnGotFocus(EventArgs e) protected override void Dispose(bool disposing)
{
if (disposing)
{ {
var handle = WindowHandle; _root?.Dispose();
if (handle != default) _root = null;
UnmanagedMethods.SetFocus(handle);
} }
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() private void FixPosition()
{ {
var handle = WindowHandle; var handle = WindowHandle;
if (handle != default && Width > 0 && Height > 0) if (handle != default && Width > 0 && Height > 0)
UnmanagedMethods.MoveWindow(handle, 0, 0, Width, Height, true); UnmanagedMethods.MoveWindow(handle, 0, 0, Width, Height, true);
} }
/// <inheritdoc /> /// <inheritdoc />
protected override void OnResize(EventArgs e) protected override void OnResize(EventArgs e)
{ {
FixPosition(); FixPosition();
base.OnResize(e); base.OnResize(e);
} }
/// <inheritdoc /> /// <inheritdoc />
protected override void OnPaint(PaintEventArgs e) protected override void OnPaint(PaintEventArgs e)
{ {
}
} }
} }

Loading…
Cancel
Save