Silverlight 插件定义在其中显示基于 Silverlight 的应用程序的区域。可以将该插件嵌入到某一宿主 HTML 页中,并且可以将该插件以内联方式定位到 HTML 页显示的某个位置,也可以使该插件占据整个 HTML 页。因此,定位 Silverlight 对象时,有两个参考框架:
布局一词描述在基于 Silverlight 的应用程序中调整对象大小和定位对象的过程。要定位可视化对象,您必须将它们放置于 Panel 或其他容器对象中。父 Panel 定义了确定如何在屏幕上绘制 Panel 元素的 Children 集合成员的布局行为。这是一个计算密集型过程,即 Children 集合越大,执行的计算次数就越多。根据拥有该集合的 Panel元素所定义的布局行为,还可能会增加复杂性。如果不需要较为复杂的 Panel(如 Grid),则可以使用构造相对简单的布局(如 Canvas),这种布局可产生更佳的性能。
每当子 UIElement 改变其位置时,布局系统就可能触发一个新的处理过程。因此,了解哪些事件会调用布局系统就很重要,因为不必要的调用可能导致应用程序性能变差。
简单地说,布局是一个递归系统,实现在屏幕上对元素进行大小调整、定位和绘制。布局系统为 Children 集合的每个成员完成两个处理过程:第一个是测量处理过程,第二个是排列处理过程。测量处理过程是确定每个子元素所需大小的过程。排列处理过程是最终确定每个子元素的大小和位置的过程。
若要重写默认 Panel 布局行为,则每个类型的 Panel 均需要提供自己的 MeasureOverride 和 ArrangeOverride 方法,以实现自己特定的布局行为。不论何时调用布局系统,都会发生以下系列事件:
-
测量每个子 UIElement。
-
计算在 FrameworkElement 上定义的大小调整属性,例如 Width、Height 和 Margin。
-
应用 Panel 特定的逻辑,例如堆栈 Orientation。
-
测量所有子元素后排列内容。
-
Children 集合绘制到屏幕。
-
如果其他 Children 添加到了集合中、Children 的布局属性(如 Width 和 Height)发生了改变或调用了 UpdateLayout 方法,均会再次调用该过程。
下面的章节将更详尽地定义此过程及其调用方式。
基于 Silverlight 的应用程序中的所有元素周围都围绕着一个边界框,了解这一点非常重要。这有助于您理解布局系统的行为。当布局系统定位任何 FrameworkElement时,实际上是在定位包含该元素的矩形或布局槽。
LayoutInformation 类将被公开,以返回元素的布局槽和可视化区域的几何边界。布局槽的大小是由系统通过计算可用屏幕空间、任何约束的大小、布局特定的属性(如边距和填充)及父 Panel 元素的个别行为来确定的。通过此数据,系统将能够计算给定的 Panel 的所有子元素的位置。牢记在父元素上定义的哪些大小调整特性(如Border)会影响其子元素,这非常重要。
下图演示了父面板、其子元素以及包含该子元素的布局槽的尺寸。
可以看到,为该子元素分配的区域实际远远大于该子元素。由父容器决定每个子元素的布局槽大小。父容器分配的空间既可大于也可小于子元素请求的空间。可以通过调用 GetLayoutSlot 来获得布局槽的尺寸。然后,父容器根据在子元素上设置的对齐方式属性将子元素定位到其布局槽内。
下图演示了一个子元素,该子元素进行了旋转,并且现在超出了分配给它的布局槽。
在这种情况下,布局系统将裁剪子元素,并且仅显示布局槽内适合的元素部分。此可视化区域(轮廓为红色)称为布局裁剪,可以通过调用 GetLayoutClip 来获得其尺寸。请注意,GetLayoutClip 会返回一个 Geometry 对象,因此此可视化区域不一定是矩形。
当元素需要呈现到屏幕时或者元素的大小发生更改时,将调用布局系统。布局的第一个处理过程是测量处理过程,将在该过程中确定每个子元素的所需大小。第二个处理过程是排列处理过程,将在该过程中确定每个子元素边界框的最终大小和位置。
测量
在测量处理过程中,布局系统会告诉 Panel 其 availableSize。这是父元素可用来为 Panel 设置其子元素的布局的区域。Panel 将计算其每个子元素的本机大小属性,如Clip 和 Visibility。
接下来,处理在每个子元素上定义的 FrameworkElement 属性。这些属性旨在描述基础 UIElement 的大小调整特性,例如其 Height、Width、Margin 和 Style。上述每个属性均可能改变显示元素所必需的空间。然后,Panel 将对其每个子元素调用 Measure 方法,以便传递相应子元素的可用大小。可用大小可以是子元素请求的大小,但父元素也可以根据它需要布局的元素数量及其 availableSize 选择限制子元素的大小。
在 Height、Width、ActualHeight 和 ActualWidth 的属性之间存在着差异。例如,ActualHeight 属性是基于其他高度输入和布局系统的计算值。该值是由布局系统本身基于实际呈现处理过程设置的,因此可能会稍微小于作为输入更改基础的 Height 等属性的设置值。由于默认值为 0,因此必须设置 Height 和 Width。 由于 ActualHeight 是一个计算值,所以您应该知道,作为布局系统多个操作的结果,该值可能有多次或不断增加的报告的更改。布局系统可能正在计算子元素所需的测量空间、父元素的约束等。 |
测量处理过程的最终目标是让布局系统确定每个子元素的 DesiredSize,这是在调用 Measure 之后在内部发生的。将存储该值,并在排列过程期间使用它。
排列
Silverlight 包括 Panel 元素的派生套件,可以实现许多复杂的布局。常见方案(如堆栈元素)可以使用 StackPanel 元素方便地实现,而较为复杂的布局可以使用 Grid 来实现。
下表概括了可用的布局元素。
面板名称 |
说明 |
---|---|
定义由行和列组成的灵活网格区域。 |
|
将子元素排列成一行(可沿水平或垂直方向)。 |
上述每个布局容器都要考虑可能影响子元素排列方式的不同属性。下表显示了几个此类常见属性。
属性名 |
布局影响 |
---|---|
在对象及其布局槽之间创建空间。 |
|
将对象定位到其布局槽内。 |
|
除了应用面板布局逻辑外,您还可以使用变换和动画来更改对象的位置。有关更多信息,请参见变换和动画。
在需要不可能使用任一预定义的 Panel 元素来实现的应用程序布局的情况下,自定义布局行为可以通过以下方式来实现:从 Panel 继承并使用 MeasureOverride 和ArrangeOverride 方法重写默认度量和排列行为。有关更多信息,请参见 自定义面板。
尽管使用 Canvas 对对象进行绝对定位在某些情况下很有用,但是在大小可变的浏览器窗口中,这通常是一个很糟糕的策略。绝对定位不允许对象根据浏览器窗口的大小调整在页面上重新排列,对象保留在各自的指定像素位置。
StackPanel 和 Grid 允许内容重新排列。Grid 对象是 Visual Studio Silverlight 模板使用的根元素。尽管在使用方面 Grid 对象比其他 Panel 对象要复杂一些,但是它支持内容的重新排列,并且其灵活性足以使您创建各种对象布局。
要获得最佳的窗口大小调整行为(除了使用 Panel 对象定位子对象外),通常来说最好的办法是将 DOM 的宽度和高度属性保留为 100%,并且在 XAML 文件的根元素或布局根元素中不包含任何宽度或高度声明。例如,在下面的 XAML 中,根元素或布局元素都没有定义宽度或高度。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。