控件可能不按预期的方式重叠。 Windows 窗体为每个控件使用单独的 HWND。 WPF 为一个页面上的所有内容使用一个 HWND。 这一实现差异会导致意外的重叠行为。

WPF 中托管的 Windows 窗体控件始终显示在 WPF 内容顶部。

ElementHost 控件中托管的 WPF 内容以 ElementHost 控件的 z 顺序显示。 可以重叠 ElementHost 控件,但托管的 WPF 内容不能组合或交互。

WindowsFormsHost ElementHost 类只能托管单个子控件或元素。 若要承载多个控件或元素,则必须使用容器作为子内容。 例如,可以向 System.Windows.Forms.Panel 控件添加 Windows 窗体按钮和复选框控件,然后将该面板分配给 WindowsFormsHost 控件的 Child 属性。 但是,不能将按钮和复选框控件分别添加到相同的 WindowsFormsHost 控件。

WPF 和 Windows 窗体具有不同的缩放模型。 某些 WPF 缩放变换对于 Windows 窗体控件是有意义的,但其他变换是无意义的。 例如,将 Windows 窗体控件缩放到 0 是可行的,但如果尝试将同一控件重新缩放回非零值,该控件的大小仍然为 0。 有关详细信息,请参阅 WindowsFormsHost 元素的布局注意事项

在使用 WindowsFormsHost ElementHost 类时可能会发生混乱,因为它们包含一个隐藏容器。 WindowsFormsHost ElementHost 类都具有一个名为“适配器”的隐藏容器,用来托管内容。 对于 WindowsFormsHost 元素,适配器派生自 System.Windows.Forms.ContainerControl 类。 对于 ElementHost 控件,适配器派生自 DockPanel 元素。 如果你发现其他互操作主题中提到了适配器,那么所讨论的就是此容器。

不支持在 ElementHost 控件内嵌套 WindowsFormsHost 元素。 也不支持在 WindowsFormsHost 元素内嵌套 ElementHost 控件。

焦点在 WPF 和 Windows 窗体中的工作方式是不同的,这意味着混合应用程序中可能发生焦点问题。 例如,如果 WindowsFormsHost 元素内部具有焦点,那么,当最小化并还原页面,或者显示模式对话框时, WindowsFormsHost 元素内部的焦点可能会丢失。 WindowsFormsHost 元素仍然具有焦点,但该元素内部的控件可能不具有焦点。

焦点还会影响数据验证。 验证在 WindowsFormsHost 元素中有效,但当按 Tab 离开 WindowsFormsHost 元素或在两个不同的 WindowsFormsHost 元素之间切换时,验证无效。

某些属性映射需要先进行大量的转译,才能将 WPF 和 Windows 窗体技术之间不同的实现桥接起来。 属性映射可使代码对字体、颜色和其他属性的更改做出反应。 通常,属性映射的工作方式是侦听 Property Changed 事件或 On Property 调用,然后在子控件或其适配器上设置适当的属性。 有关详细信息,请参阅 Windows 窗体和 WPF 属性映射

分配 WindowsFormsHost.Child ElementHost.Child 属性后,会自动设置托管内容上的几个与布局相关的属性。 更改这些内容属性可能会导致意外的布局行为。

停靠托管内容以填充 WindowsFormsHost ElementHost 父级。 为了启用此填充行为,在设置子属性时,将设置多个属性。 下表列出了由 ElementHost WindowsFormsHost 类设置的内容属性。

导航应用程序不能保持用户状态。 在导航应用程序中使用 WindowsFormsHost 元素时,该元素将重新创建其控件。 当用户通过导航操作离开托管 WindowsFormsHost 元素的页面,然后又返回到该页面时,将发生重新创建子控件的操作。 用户已经键入的所有内容都将丢失。

消息循环互操作

在使用 Windows 窗体消息循环时,可能无法按照预期方式处理消息。 EnableWindowsFormsInterop 方法由 WindowsFormsHost 构造函数调用。 此方法将向 WPF 消息循环中添加消息筛选器。 如果 System.Windows.Forms.Control 是消息的目标,则此筛选器会调用 Control.PreProcessMessage 方法并转换/调度该消息。

如果在使用 Application.Run 的 Windows 窗体消息循环中显示 Window ,则除非调用 EnableModelessKeyboardInterop 方法,否则不能键入任何内容。 EnableModelessKeyboardInterop 方法采用 Window 并添加 System.Windows.Forms.IMessageFilter ,将与密钥相关的消息重新路由到 WPF 消息循环。 有关详细信息,请参阅 Windows 窗体和 WPF 互操作性输入体系结构

不透明度和分层

HwndHost 类不支持分层。 这意味着在 WindowsFormsHost 元素上设置 Opacity 属性不起作用,并且不会与将 AllowsTransparency 设置为 true 的其他 WPF 窗口产生混合效果。

未正确释放类可能会泄漏资源。 在混合应用程序中,请确保释放 WindowsFormsHost ElementHost 类,否则可能会泄漏资源。 Windows 窗体在其非模式 Form 父级关闭时释放 ElementHost 控件。 WPF 会在应用程序关闭时释放 WindowsFormsHost 元素。 可以在 Windows 窗体消息循环中的 Window 中显示 WindowsFormsHost 元素。 在这种情况下,代码可能不会收到应用程序正在关闭的通知。

启用视觉样式

可能无法启用 Windows 窗体控件上的 Microsoft Windows XP 视觉样式。 Application.EnableVisualStyles 方法在 Windows 窗体应用程序的模板中调用。 尽管默认情况下不会调用此方法,但如果使用 Visual Studio 创建项目,并且 Comctl32.dll 版本 6.0 可用,将会获得控件的 Microsoft Windows XP 视觉样式。 在线程上创建句柄之前,必须先调用 EnableVisualStyles 方法。 有关详细信息,请参阅 如何:在混合应用程序中启用视觉样式

授权的 Windows 窗体控件会在消息框中向用户显示许可信息,对于混合应用程序,这可能会导致意外行为。 某些授权控件会显示一个对话框来响应创建句柄的操作。 例如,授权控件可能会通知用户需要许可证,或者用户还可以试用该控件三次。

WindowsFormsHost 元素派生自 HwndHost 类,子控件的句柄将在 BuildWindowCore 方法内创建。 HwndHost 类不允许在 BuildWindowCore 方法中处理消息,但显示对话框会导致发送消息。 要启用此许可方案,请先调用控件上的 Control.CreateControl 方法,然后再将其分配为 WindowsFormsHost 元素的子级。

WPF 设计器

可以使用适用于 Visual Studio 的 WPF 设计器设计 WPF 内容。 以下部分列出了在使用 WPF 设计器创作混合应用程序时可能发生的一些常见问题。

在设计时忽略 BackColorTransparent

BackColorTransparent 属性在设计时可能无法按预期工作。

如果 WPF 控件不在可见的父级上,WPF 运行时会忽略 BackColorTransparent 值。 可能忽略 BackColorTransparent 的原因是, ElementHost 对象是在单独的 AppDomain 中创建的。 但在运行应用程序时, BackColorTransparent 会按预期工作。

删除 obj 文件夹时出现设计时错误列表

如果删除 obj 文件夹,会出现设计时错误列表。

使用 ElementHost 进行设计时,Windows 窗体设计器将使用项目的 obj 文件夹内 Debug 或 Release 文件夹中生成的文件。 如果删除这些文件,将出现设计时错误列表。 若要解决此问题,请重新生成项目。 有关详细信息,请参阅 Windows 窗体设计器中的设计时错误

ElementHost 和 IME

ElementHost 中托管的 WPF 控件当前不支持 ImeMode 属性。 托管的控件将忽略对 ImeMode 所做的更改。

  • ElementHost
  • WindowsFormsHost
  • WPF 设计器中的互操作性
  • Windows 窗体和 WPF 互操作性输入体系结构
  • 如何:在混合应用程序中启用视觉对象样式
  • WindowsFormsHost 元素的布局注意事项
  • Windows 窗体和 WPF 属性映射
  • Windows 窗体设计器中的设计时错误
  • 迁移和互操作性
  •