WindowsFormsHost 元素的布局注意事项

本主题介绍 WindowsFormsHost 元素如何与 WPF 布局系统交互。

WPF 和 Windows 窗体支持用于调整窗体或页面上元素大小和定位的不同但相似的逻辑。 在 WPF 中创建托管 Windows 窗体控件的混合用户界面(UI),该 WindowsFormsHost 元素将集成这两种布局方案。

WPF 和 Windows 窗体布局的差异

WPF 使用与分辨率无关的布局。 所有 WPF 布局尺寸都使用 与设备无关的像素指定。 与设备无关的像素是每英寸的九十六分之一,其大小和分辨率独立,因此无论是在 72 dpi 的显示器上渲染,还是在 19,200 dpi 的打印机上渲染,您都会获得类似的结果。

WPF 还基于 动态布局。 这意味着 UI 元素根据窗体或页面上的内容、父布局容器和可用的屏幕大小排列自身。 动态布局通过在包含更改长度的字符串时自动调整 UI 元素的大小和位置,从而促进本地化。

Windows 窗体中的布局依赖于设备,并且更有可能是静态的。 通常,Windows 窗体控件根据硬件像素指定的尺寸绝对定位在窗体上。 但是,Windows 窗体确实支持一些动态布局功能,如下表所述。

布局功能 DESCRIPTION
自动调整大小 某些 Windows 窗体控件调整自身大小以正确显示其内容。 有关详细信息,请参阅 AutoSize 属性概述
定位和停靠 Windows 窗体控件支持根据父容器来定位和调整大小。 有关详细信息,请参阅 Control.AnchorControl.Dock
自动缩放 容器控件根据输出设备分辨率或默认容器字体的大小(以像素为单位)调整自身及其子级的大小。 有关详细信息,请参阅 Windows 窗体中的自动缩放
布局容器 控件FlowLayoutPanelTableLayoutPanel根据其内容排列其子控件并调整其大小。

布局限制

通常,Windows 窗体控件无法像 WPF 控件那样灵活进行缩放和转换。 以下列表描述了在 WindowsFormsHost 元素尝试将其托管的 Windows 窗体控件集成到 WPF 布局系统时的已知限制。

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

  • 无法旋转或倾斜 Windows 窗体控件。 如果应用倾斜或旋转转换,WindowsFormsHost元素将引发LayoutError事件。 如果您没有处理 LayoutError 事件,将会触发一个 InvalidOperationException

  • 在大多数情况下,Windows 窗体控件不支持比例缩放。 尽管控件的整体维度将缩放,但控件的子控件和组件元素可能无法按预期调整大小。 此限制取决于每个 Windows 窗体控件对缩放的支持程度。 此外,不能将 Windows 窗体控件缩小到大小 0 像素。

  • Windows 窗体控件支持自动缩放,其中窗体将根据字号自动调整自身大小及其控件的大小。 在 WPF 用户界面中,更改字体大小不会调整整个布局的大小,尽管单个元素可以动态调整大小。

Z 顺序

在 WPF 用户界面中,可以更改元素的 z 顺序来控制重叠行为。 托管的 Windows 窗体控件在单独的 HWND 中绘制,因此它始终在 WPF 元素的顶部绘制。

托管的 Windows 窗体控件也会在任何 Adorner 元素之上绘制。

布局行为

以下部分介绍在 WPF 中托管 Windows 窗体控件时布局行为的特定方面。

缩放、单元转换和设备独立性

每当 WindowsFormsHost 元素执行涉及 WPF 和 Windows 窗体维度的作时,都会涉及两个坐标系:WPF 的设备无关像素和 Windows 窗体的硬件像素。 因此,必须应用适当的单位和缩放转换才能实现一致的布局。

坐标系之间的转换取决于当前设备分辨率以及应用于 WindowsFormsHost 元素或其祖先的任何布局或渲染转换。

如果输出设备为 96 dpi 且未对元素应用 WindowsFormsHost 任何缩放,则一个与设备无关的像素等于一个硬件像素。

所有其他情况都需要坐标系缩放。 托管控件没有被调整大小。 相反,该 WindowsFormsHost 元素会尝试缩放托管控件及其所有子控件。 由于 Windows 窗体不完全支持缩放,WindowsFormsHost 元素会根据特定控件的支持水平进行缩放。

重写ScaleChild方法,为托管的 Windows 窗体控件提供自定义缩放行为。

除了缩放之外,元素 WindowsFormsHost 还处理舍入和溢出情况,如下表所述。

转换问题 DESCRIPTION
舍入 WPF 与设备无关的像素尺寸指定为 double,Windows 窗体硬件像素尺寸指定为 int。 在基于double的维度转换为基于int的维度的情况下,WindowsFormsHost元素使用标准舍入方式,以便小于 0.5 的分数值向下舍入为 0。
溢出 WindowsFormsHost 元素从 double 值转换为 int 值时,可能会溢出。 大于 MaxValue 的值被设为 MaxValue

Windows 窗体控件和 WPF 元素中控件布局行为的属性由 WindowsFormsHost 元素适当映射。 有关详细信息,请参阅 Windows 窗体和 WPF 属性映射

托管控件中的布局更改

在托管的 Windows 窗体控件中,布局更改会传播到 WPF,以促使更新布局。 InvalidateMeasure 方法在 WindowsFormsHost 上可确保托管控件中的布局更改触发 WPF 布局引擎的运行。

持续调整大小的 Windows 窗体控件

支持持续缩放的 Windows 窗体控件与 WPF 布局系统完全交互。 该 WindowsFormsHost 元素像往常一样使用 MeasureOverrideArrangeOverride 方法调整托管的 Windows 窗体控件的大小和排列方式。

尺寸算法

WindowsFormsHost 元素使用以下过程调整托管控件的大小:

  1. WindowsFormsHost 元素重写了 MeasureOverrideArrangeOverride 方法。

  2. 为了确定托管控件的大小,MeasureOverride 方法会使用从传递给 MeasureOverride 方法的约束转换而来的约束来调用托管控件的 GetPreferredSize 方法。

  3. 该方法 ArrangeOverride 尝试将托管控件设置为给定的大小约束。

  4. 如果托管控件 Size 的属性与指定的约束匹配,则托管控件的大小将调整为约束。

Size如果属性与指定的约束不匹配,则托管控件不支持连续大小调整。 例如,控件 MonthCalendar 只允许离散大小。 此控件的允许大小由整数(表示高度和宽度的月数)组成。 在这种情况下,元素 WindowsFormsHost 的行为如下所示:

  • 如果Size属性返回的大小大于指定的约束,则WindowsFormsHost元素将裁剪托管控件。 高度和宽度是单独处理的,因此托管控件可以按任一方向剪裁。

  • Size如果属性返回的大小比指定的约束小,WindowsFormsHost则接受此大小值,并将该值返回到 WPF 布局系统。

另请参阅