WPF 和 Windows 窗体互操作
WPF 和 Windows 窗体提供两种用于创建应用程序接口的不同体系结构。 System.Windows.Forms.Integration 命名空间提供实现常见互操作方案的类。 实现互操作功能的两个关键类是 WindowsFormsHost 和 ElementHost。 本主题介绍支持哪些互操作方案以及不支持哪些互操作方案。
注意
关于混合控件方案,需要考虑一些特殊因素。 混合控件将一种技术中的控件嵌套于另一种技术中的控件。 这也称为嵌套互操作。 多级混合控件具有多个级别的混合控件嵌套。 多级嵌套互操作的一个示例是包含 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 窗体控件不支持透明度。 例如,TextBox 和 ComboBox 控件在由 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 属性值为 true 的 TextBox 控件中按 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 控件之间的操作。 | 不适用。 |