WPF 和 Windows 窗体互操作

WPF 和 Windows Forms提供两种用于创建应用程序接口的不同体系结构。 System.Windows.Forms.Integration 命名空间提供实现常见互操作方案的类。 实现互操作功能的两个关键类是 WindowsFormsHostElementHost。 本主题介绍支持哪些互操作方案以及不支持哪些互操作方案。

注意注意

关于混合控件方案,需要考虑一些特殊因素。混合控件将一种技术中的控件嵌套于另一种技术中的控件。这也称为“嵌套互操作”。多级混合控件具有多个级别的混合控件嵌套。多级嵌套互操作的一个示例是包含 WPF 控件的 Windows Forms控件,前者又包含另一个 Windows Forms控件。不支持多级混合控件。

本主题包括下列各节。

  • 在 WPF 中承载 Windows 窗体控件
  • 在 Windows 窗体中承载 WPF 控件
  • 相关主题

在 WPF 中承载 Windows 窗体控件

当 WPF 控件承载一个 Windows Forms控件时,支持下列互操作方案:

  • WPF 控件可以使用 XAML 承载一个或多个 Windows Forms控件。

  • 它可以使用代码承载一个或多个 Windows Forms控件。

  • 它可以承载包含其他 Windows Forms控件的 Windows Forms容器控件。

  • 它可以承载具有 WPF 母版和 Windows Forms详细信息的母版/详细信息窗体。

  • 它可以承载具有 Windows Forms母版和 WPF 详细信息的母版/详细信息窗体。

  • 它可以承载一个或多个 ActiveX 控件。

  • 它可以承载一个或多个复合控件。

  • 它可以使用Extensible Application Markup Language (XAML) 承载混合控件。

  • 它可以使用代码承载混合控件。

布局支持

下面介绍了当 WindowsFormsHost 元素尝试将其承载的 Windows Forms控件集成到 WPF 布局系统时的已知限制。

  • 某些情况下,Windows Forms控件无法调整大小,或者大小只能调整为特定的尺寸。 例如,Windows Forms ComboBox 控件仅支持由控件的字号定义的单一高度。 在元素可以垂直拉伸的 WPF 动态布局中,承载的 ComboBox 控件不会如预期那样拉伸。

  • Windows Forms控件不能旋转或扭曲。 例如,当您将用户界面旋转 90 度时,所承载的 Windows Forms控件将保持其垂直位置。

  • 某些情况下,Windows Forms控件不支持按比例缩放。 尽管该控件的整体尺寸将会缩放,但其子控件和组件元素可能不会如预期那样调整大小。 此限制取决于每个 Windows Forms控件支持缩放的程度。

  • 在 WPF 用户界面中,您可以更改元素的 z 顺序以控制重叠行为。 由于承载的 Windows Forms控件是在单独的 HWND 中绘制的,所以它始终绘制在 WPF 元素的顶部。

  • Windows Forms控件支持基于字号的自动缩放。 在 WPF 用户界面中,更改字号不会改变整个布局的大小,不过个别元素可能会动态调整大小。

环境属性

WPF 控件的一些环境属性具有 Windows Forms等效项。 这些环境属性传播到所承载的 Windows Forms控件,并作为 WindowsFormsHost 控件的公共属性公开。 WindowsFormsHost 控件将每个 WPF 环境属性转换为它的 Windows Forms等效项。

有关更多信息,请参见Windows 窗体和 WPF 属性映射

行为

下表介绍互操作行为。

行为

是否支持

不支持

透明度

Windows Forms控件呈现支持透明度。 父 WPF 控件的背景可以成为所承载的 Windows Forms控件的背景。

某些 Windows Forms控件不支持透明度。 例如,TextBoxComboBox 控件在由 WPF 承载时将不会是透明的。

Tab 键

所承载的 Windows Forms控件的 Tab 键顺序与这些控件承载于基于 Windows Forms的应用程序中时是一样的。

使用 Tab 键和 Shift+Tab 键从 WPF 控件切换到 Windows Forms控件将按常规方式工作。

当用户按 Tab 键依次通过多个控件时,具有值为 false 的 TabStop 属性的 Windows Forms控件不会获得焦点。

  • 每个 WindowsFormsHost 控件都有一个 TabIndex 值,这决定了该 WindowsFormsHost 控件获得焦点的时间。

  • 包含在 WindowsFormsHost 容器内部的 Windows Forms控件遵循 TabIndex 属性指定的顺序。 从最后一个 Tab 键索引使用 Tab 键会将焦点置于下一个 WPF 控件上(如果存在的话)。 如果没有其他可设定焦点的 WPF 控件存在,按 Tab 键将返回到 Tab 键顺序中的第一个 Windows Forms控件。

  • WindowsFormsHost 内部控件的 TabIndex 值是相对于 WindowsFormsHost 控件中包含的同级 Windows Forms控件而言的。

  • Tab 键会遵循特定控件的行为。 例如,在具有值为 true 的 AcceptsTab 属性的 TextBox 控件中按 Tab 键会在文本框中输入一个制表符,而不是移动焦点。

不适用。

使用箭头键进行导航

  • WindowsFormsHost 控件中使用箭头键进行导航与在普通的 Windows Forms容器控件中相同:上箭头键和左箭头键选择上一个控件,下箭头键和右箭头键选择下一个控件。

  • WindowsFormsHost 控件中包含的第一个控件按上箭头键和左箭头键与 Shift+Tab 键盘快捷方式所执行的操作相同。 如果存在可设定焦点的 WPF 控件,则焦点将移到 WindowsFormsHost 控件的外部。 此行为与标准 ContainerControl 行为的不同之处在于,不回到最后一个控件。 如果没有其他可设定焦点的 WPF 控件存在,焦点将返回到 Tab 键顺序中的最后一个 Windows Forms控件。

  • WindowsFormsHost 控件中包含的最后一个控件按下箭头键和右箭头键将执行与 Tab 键相同的操作。 如果存在可设定焦点的 WPF 控件,则焦点将移到 WindowsFormsHost 控件的外部。 此行为与标准 ContainerControl 行为的不同之处在于,不回到第一个控件。 如果没有其他可设定焦点的 WPF 控件存在,焦点将返回到 Tab 键顺序中的第一个 Windows Forms控件。

不适用。

快捷键

快捷键按常规方式工作,但在“不支持”列中指出的情况除外。

不同技术中的重复快捷键不会像普通的重复快捷键那样工作。 当在不同技术之间重复快捷键,并且至少一个在 Windows Forms控件上,另一个在 WPF 控件上时,Windows Forms控件将总是接收该快捷键。 当按重复快捷键时,焦点不会在控件之间切换。

快捷键

快捷键按常规方式工作,但在“不支持”列中指出的情况除外。

  • 在预处理阶段处理的 Windows Forms快捷键总是优先于 WPF 快捷键。 例如,如果您有一个定义了 Ctrl+S 快捷键的 ToolStrip 控件,并且存在绑定于 Ctrl+S 的 WPF 命令,则 ToolStrip 控件处理程序将总是首先调用,而不管焦点具体在哪个控件上。

  • KeyDown 事件处理的 Windows Forms快捷键在 WPF 中最后处理。 您可以通过重写 Windows Forms控件的 IsInputKey 方法或处理 PreviewKeyDown 事件来防止此行为。 从 IsInputKey 方法返回 true,或者在 PreviewKeyDown 事件处理程序中将 PreviewKeyDownEventArgs.IsInputKey 属性的值设置为 true。

AcceptsReturn、AcceptsTab 以及其他特定于控件的行为

更改默认键盘行为的属性按常规方式工作,前提是 Windows Forms控件重写 IsInputKey 方法以返回 true。

通过处理 KeyDown 事件来更改默认键盘行为的 Windows Forms控件在 WPF 宿主控件中最后一个处理。 因为这些控件在最后处理,所以可能产生意外的行为。

Enter 和 Leave 事件

如果焦点未转到 ElementHost 包含控件,那么当焦点在一个 WindowsFormsHost 控件中更改时,将会像通常那样引发 Enter 和 Leave 事件。

当发生以下焦点更改时,不会引发 Enter 和 Leave 事件:

多线程处理

支持所有类型的多线程。

Windows Forms和 WPF 技术均采用单线程并发模型。 调试期间,从其他线程调用框架对象会引发一个异常,从而强制满足此要求。

安全性

所有互操作方案都需要完全信任。

在部分信任下不允许任何互操作方案。

辅助功能

支持所有辅助功能方案。 当辅助技术产品用于同时包含 Windows Forms和 WPF 控件的混合应用程序时,可正常工作。

不适用。

Clipboard

所有剪贴板操作都按常规方式工作。 这包括 Windows Forms与 WPF 控件之间的剪切和粘贴。

不适用。

拖放功能

所有拖放操作都按常规方式工作。 这包括 Windows Forms与 WPF 控件之间的操作。

不适用。

在 Windows 窗体中承载 WPF 控件

当 Windows Forms控件承载一个 WPF 控件时,支持下列互操作方案:

  • 使用代码承载一个或多个 WPF 控件。

  • 将属性表与一个或多个承载的 WPF 控件关联。

  • 在一个窗体中承载一个或多个 WPF 页。

  • 启动 WPF 窗口。

  • 承载具有 Windows Forms母版和 WPF 详细信息的母版/详细信息窗体。

  • 承载具有 WPF 母版和 Windows Forms详细信息的母版/详细信息窗体。

  • 承载自定义 WPF 控件。

  • 承载混合控件。

环境属性

Windows Forms控件的一些环境属性具有 WPF 等效项。 这些环境属性传播到所承载的 WPF 控件,并作为 ElementHost 控件的公共属性公开。 ElementHost 控件将每个 Windows Forms环境属性转换为它的 WPF 等效项。

有关更多信息,请参见Windows 窗体和 WPF 属性映射

行为

下表介绍互操作行为。

行为

是否支持

不支持

透明度

WPF控件呈现支持透明度。 父 Windows Forms控件的背景可以成为所承载的 WPF 控件的背景。

不适用。

多线程处理

支持所有类型的多线程。

Windows Forms和 WPF 技术均采用单线程并发模型。 调试期间,从其他线程调用框架对象会引发一个异常,从而强制满足此要求。

安全性

所有互操作方案都需要完全信任。

在部分信任下不允许任何互操作方案。

辅助功能

支持所有辅助功能方案。 当辅助技术产品用于同时包含 Windows Forms和 WPF 控件的混合应用程序时,可正常工作。

不适用。

Clipboard

所有剪贴板操作都按常规方式工作。 这包括 Windows Forms与 WPF 控件之间的剪切和粘贴。

不适用。

拖放功能

所有拖放操作都按常规方式工作。 这包括 Windows Forms与 WPF 控件之间的操作。

不适用。

请参见

任务

演练:在 WPF 中承载 Windows 窗体控件

参考

ElementHost

WindowsFormsHost

概念

演练:在 WPF 中承载 Windows 窗体复合控件

演练:在 Windows 窗体中承载 WPF 复合控件

Windows 窗体和 WPF 属性映射