8

このブログのコードを以下のように要約して使用しました。メイン ウィンドウ内に 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>
4

1 に答える 1

9
  <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 に設定して、境界線を取り除きます。など。

フォームの TopLevel プロパティを false に設定し、Visible プロパティを true に設定すると、フォームを子コントロールに変換するより簡単な方法になります。Delphiウィンドウに同じ扱いをしたいかもしれないとあなたがほのめかしたので、私はそれをこのままにしました。その場合、元のアプローチに戻り、フォーム クラス コンストラクターで子を作成し、XAML でコンテンツの割り当てを省略したい場合があります。

于 2013-12-24T10:10:54.413 に答える