简体   繁体   English

为什么我的WPF托管WinForm空白?

[英]Why is my WPF hosted WinForm blank?

I have used the code from this blog , as below but abridged, and I see the WinForm inside my main window, but the sample text I placed on it in a label is not visible. 我已经使用了这个博客中的代码,如下所示,但是我在主窗口中看到了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; 
  }
}

And: 和:

<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>
  <cc:WinFormsHost ShowCaption="False">
    <wf:Form/>
  </cc:WinFormsHost>

Your XAML embeds a System.Windows.Forms.Form object inside the WinFormsHost. 您的XAML在WinFormsHost中嵌入了一个System.Windows.Forms.Form对象。 Which is what you got, just a blank form with no child controls embedded inside it. 这是你得到的,只是一个没有嵌入子控件的空白表单。 It looks like you made an attempt at creating your own in the WinFormsHost constructor, assigning the Child property, but your XAML is overriding it so you are just left with a blank form again. 看起来你试图在WinFormsHost构造函数中创建自己的属性,分配Child属性,但是你的XAML会覆盖它,所以你只剩下一个空白表单了。

I put a ChildForm class inside the same namespace: 我将一个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);
    }
}

And updated the XAML to: 并将XAML更新为:

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

To get: 要得到:

在此输入图像描述

Set the FormBorderStyle to None to get rid of the border. 将FormBorderStyle设置为None以摆脱边框。 Etcetera. 等等。

Setting the form's TopLevel property to false and Visible property to true is the much simpler way to turn a Form into a child control btw. 将窗体的TopLevel属性设置为false,将Visible属性设置为true是将窗体转换为子控件btw的简单方法。 I left it this way since you hinted you might want to give a Delphi window the same treatment. 我这样离开了,因为你暗示你可能想给Delphi窗口一样的处理。 In which case you might want to go back to your original approach again, creating the child in the form class constructor and just omitting the content assignment in the XAML. 在这种情况下,您可能希望再次返回到原​​始方法,在表单类构造函数中创建子项,并且只省略XAML中的内容分配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM