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.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);
}
}
}

147
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)
{
}
}
}

Loading…
Cancel
Save