Почему мой WPF-хост WinForm пуст?

Я использовал код из этого блога, как показано ниже, но в сокращенном виде, и я вижу WinForm внутри моего основного окна, но образец текста, который я поместил в него в метке, не виден.

[System.Windows.Markup.ContentProperty("Child")]
public class WinFormsHost : HwndHost
{
  public WinFormsHost()
  {
    var form = new ChildForm();
    Child = form;
  }
  private System.Windows.Forms.Form child;
  public event EventHandler<ChildChangedEventArgs> ChildChanged;
  public System.Windows.Forms.Form Child
  {
    get { return child; }
    set
    {
      HwndSource ps = PresentationSource.FromVisual(this) as HwndSource;
      if (ps != null && ps.Handle != IntPtr.Zero)
      {
        throw new InvalidOperationException("Cannot set the Child property after the layout is done.");
      }
      Form oldChild = child;
      child = value;
      OnChildChanged(oldChild);
    }
  }

  private void CheckChildValidity()
  {
    if (child == null || child.Handle == IntPtr.Zero)
    {
      throw new ArgumentNullException("child form cannot be null");
    }
  }

  public Boolean ShowCaption
  {
    get
    {
      CheckChildValidity();
      return (GetWindowStyle(Child.Handle) & WindowStyles.WS_BORDER) == WindowStyles.WS_CAPTION;
    }
    set
    {
      if (child == null)
      {
        this.ChildChanged += delegate
        {
          if (value)
          {
            SetWindowStyle(Child.Handle, GetWindowStyle(Child.Handle) | WindowStyles.WS_CAPTION);
          }
          else
          {
            SetWindowStyle(Child.Handle, GetWindowStyle(Child.Handle) & ~WindowStyles.WS_CAPTION);
          }
        };
      }
      else
      {
        if (value)
        {
          SetWindowStyle(Child.Handle, GetWindowStyle(Child.Handle) | WindowStyles.WS_CAPTION);
        }
        else
        {
          SetWindowStyle(Child.Handle, GetWindowStyle(Child.Handle) & ~WindowStyles.WS_CAPTION);
        }
      }
    }
  }

  protected override HandleRef BuildWindowCore(HandleRef hwndParent)
  {
    CheckChildValidity();
    HandleRef childHwnd = new HandleRef(Child, child.Handle);
    SetWindowStyle(childHwnd.Handle, WindowStyles.WS_CHILD | GetWindowStyle(childHwnd.Handle));
    WindowsFormsHost.EnableWindowsFormsInterop();
    System.Windows.Forms.Application.EnableVisualStyles();
    SetParent(childHwnd.Handle, hwndParent.Handle);
    return childHwnd; 
  }
}

А также:

<Window x:Class="WinFormsHost" 
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms" 
   xmlns:cc="clr-namespace:XTime.Shell.WinformsHost" 
   Title="Hosting Form In WPF">
  <cc:WinFormsHost ShowCaption="False">
    <wf:Form/>
  </cc:WinFormsHost>
</Window>

1 ответ

Решение
  <cc:WinFormsHost ShowCaption="False">
    <wf:Form/>
  </cc:WinFormsHost>

Ваш XAML встраивает объект System.Windows.Forms.Form в WinFormsHost. Это то, что вы получили, просто пустая форма без встроенных дочерних элементов управления. Похоже, вы попытались создать свой собственный в конструкторе WinFormsHost, присвоив свойство Child, но ваш XAML переопределяет его, поэтому вы просто снова получаете пустую форму.

Я поместил класс ChildForm в том же пространстве имен:

using System.Windows.Forms;
using System.Drawing;
...

public class ChildForm : System.Windows.Forms.Form {
    public ChildForm() {
        this.BackColor = Color.FromKnownColor(KnownColor.Window);
        var lbl = new Label { Text = "Hello world" };
        this.Controls.Add(lbl);
    }
}

И обновил XAML для:

<cc:WinFormsHost ShowCaption="False">
    <cc:ChildForm/>
</cc:WinFormsHost>

Получить:

введите описание изображения здесь

Установите для FormBorderStyle значение None, чтобы избавиться от границы. Etcetera.

Установка свойства TopLevel формы в false и свойства Visible в true - гораздо более простой способ превратить форму в дочерний элемент управления. Я оставил это таким образом, так как вы намекнули, что вы можете использовать окно Delphi таким же образом. В этом случае вы можете захотеть вернуться к исходному подходу снова, создав дочерний элемент в конструкторе класса формы и просто пропустив назначение содержимого в XAML.

Другие вопросы по тегам