WPF 和 Windows 窗体互操作

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

注意

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

在 WPF 中承载 Windows 窗体控件

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

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

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

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

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

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

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

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

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

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

布局支持

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

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

  • 不能旋转或倾斜 Windows 窗体控件。 例如,将用户界面旋转 90 度时,所承载的 Windows 窗体控件将保持其垂直位置。

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

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

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

环境属性

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

有关详细信息,请参阅 Windows 窗体和 WPF 属性映射

行为

下表介绍互操作行为。

行为 支持 不支持
透明度 Windows 窗体控件呈现支持透明度。 父 WPF 控件的背景可以成为所承载的 Windows 窗体控件的背景。 某些 Windows 窗体控件不支持透明度。 例如,TextBoxComboBox 控件在由 WPF 承载时不会是透明的。
Tab 键次序 所承载的 Windows 窗体控件的 Tab 键顺序与这些控件承载于基于 Windows 窗体的应用程序中时是相同的。

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

当用户按 Tab 键在多个控件之间切换时,TabStop 属性值为 false 的 Windows 窗体控件不会获得焦点。

- 每个 WindowsFormsHost 控件都有一个 TabIndex 值,该值确定该 WindowsFormsHost 控件何时获得焦点。
- 包含在 WindowsFormsHost 容器内的 Windows 窗体控件遵循 TabIndex 属性指定的顺序。 从最后一个 Tab 键索引使用 Tab 键切换会将焦点置于下一个 WPF 控件上(若存在)。 如果不存在其他可聚焦的 WPF 控件,则按 Tab 键将返回到 Tab 键顺序中的第一个 Windows 窗体控件。
- WindowsFormsHost 内部控件的 TabIndex 值与 WindowsFormsHost 控件中包含的同级 Windows 窗体控件相关。
- 按 Tab 键遵循特定于控件的行为。 例如,在 AcceptsTab 属性值为 trueTextBox 控件中按 TAB 键会在文本框中输入一个制表符,而不会移动焦点。
不适用。
使用箭头键导航 - 在 WindowsFormsHost 控件中使用箭头键进行导航与在普通的 Windows 窗体容器控件中相同:向上键和向左键选择上一个控件,向下键和向右键选择下一个控件。
- 从 WindowsFormsHost 控件中包含的第一个控件按向上键和向左键与 Shift+Tab 键盘快捷方式所执行的操作相同。 如果存在可聚焦的 WPF 控件,则焦点将移到 WindowsFormsHost 控件的外部。 此行为与标准 ContainerControl 行为的不同之处是不会包装最后一个控件。 如果不存在其他可聚焦的 WPF 控件,则焦点将返回到 Tab 键顺序中的最后一个 Windows 窗体控件。
- 从 WindowsFormsHost 控件中包含的最后一个控件按向下键和向右键与 Tab 键所执行的操作相同。 如果存在可聚焦的 WPF 控件,则焦点将移到 WindowsFormsHost 控件的外部。 此行为与标准 ContainerControl 行为的不同之处是不会包装第一个控件。 如果不存在其他可聚焦的 WPF 控件,则焦点将返回到 Tab 键顺序中的第一个 Windows 窗体控件。
不适用。
加速器 加速键按常规方式工作,但“不支持”列中注明的情况除外。 跨多种技术的重复加速键与普通重复加速键的工作方式不同。 如果加速键跨多种技术复制,并且至少一个在 Windows 窗体控件上,另一个在 WPF 控件上,Windows 窗体控件将始终收到此加速键。 当按重复加速键时,焦点不会在控件之间切换。
快捷键 快捷键按常规方式工作,但“不支持”列中注明的情况除外。 - 在预处理阶段处理的 Windows 窗体快捷键总是优先于 WPF 快捷键。 例如,如果有一个定义了 Ctrl+S 快捷键的 ToolStrip 控件,并且存在绑定到 Ctrl+S 的 WPF 命令,则无论焦点在何处,总是首先调用 ToolStrip 控件处理程序。
- 由 KeyDown 事件处理的 Windows 窗体快捷键在 WPF 中最后处理。 可通过替代 Windows 窗体控件的 IsInputKey 方法或处理 PreviewKeyDown 事件来防止此行为。 从 IsInputKey 方法返回 true,或在 PreviewKeyDown 事件处理程序中将 PreviewKeyDownEventArgs.IsInputKey 属性的值设置为 true
AcceptsReturn、AcceptsTab 以及其他特定于控件的行为 更改默认键盘行为的属性按常规方式工作,前提是 Windows 窗体控件替代 IsInputKey 方法以返回 true 通过处理 KeyDown 事件来更改默认键盘行为的 Windows 窗体控件在 WPF 主机控件中最后处理。 因为最后处理这些控件,所以它们可能产生意外行为。
Enter 和 Leave 事件 如果焦点未转到包含的 ElementHost 控件,则在一个 WindowsFormsHost 控件中更改焦点时,将会像通常那样引发 Enter 和 Leave 事件。 发生以下焦点更改时,不会引发 Enter 和 Leave 事件:

- 从 WindowsFormsHost 控件的内部到外部。
- 从 WindowsFormsHost 控件的外部到内部。
- 在 WindowsFormsHost 控件外部。
- 从 WindowsFormsHost 控件中承载的 Windows 窗体控件到同一 WindowsFormsHost 中承载的 ElementHost 控件。
多线程处理 支持所有类型的多线程处理。 Windows 窗体和 WPF 技术均采用单线程并发模型。 调试期间,从其他线程调用框架对象会引发一个异常,以强制实施此要求。
安全性 所有互操作方案都需要完全信任。 部分信任情况下,不允许任何互操作方案。
可访问性 支持所有辅助功能方案。 当辅助技术产品用于同时包含 Windows 窗体和 WPF 控件的混合应用程序时,可正常工作。 不适用。
剪贴板 所有剪贴板操作按常规方式工作。 这包括 Windows 窗体与 WPF 控件之间的剪切和粘贴。 不适用。
拖放功能 所有拖放操作按常规方式工作。 这包括 Windows 窗体和 WPF 控件之间的操作。 不适用。

在 Windows 窗体中承载 WPF 控件

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

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

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

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

  • 启动 WPF 窗口。

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

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

  • 承载自定义 WPF 控件。

  • 承载混合控件。

环境属性

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

有关详细信息,请参阅 Windows 窗体和 WPF 属性映射

行为

下表介绍互操作行为。

行为 支持 不支持
透明度 WPF 控件呈现支持透明度。 父 Windows 窗体控件的背景可以成为所承载的 WPF 控件的背景。 不适用。
多线程处理 支持所有类型的多线程处理。 Windows 窗体和 WPF 技术均采用单线程并发模型。 调试期间,从其他线程调用框架对象会引发一个异常,以强制实施此要求。
安全性 所有互操作方案都需要完全信任。 部分信任情况下,不允许任何互操作方案。
可访问性 支持所有辅助功能方案。 当辅助技术产品用于同时包含 Windows 窗体和 WPF 控件的混合应用程序时,可正常工作。 不适用。
剪贴板 所有剪贴板操作按常规方式工作。 这包括 Windows 窗体与 WPF 控件之间的剪切和粘贴。 不适用。
拖放功能 所有拖放操作按常规方式工作。 这包括 Windows 窗体和 WPF 控件之间的操作。 不适用。

另请参阅