WPF自定义面板
WPF自定义面板是一种特殊但较常见的自定义控件开发子集。面板驻留一个或多个子元素,并且实现了特定的布局逻辑以恰当地安排子元素,当创建需要非标准特定布局的组合控件时,自定义面板通常很有用的
可以通过重写名称为MeasureOverride()和ArrangeOverride()方法,为这两个步骤添加自己的逻辑,这两个方法是作为WPF布局系统的一部分在FrameworkElement类中定义的。奇特的名称使用标识MeasureOverride()和ArrangeOverride()方法代替在MeasureCore()和ArrangeCore()方法中定义的逻辑,后两个方法在UIElement类中定义的。这两个方法是不能被重写的
1、MeasureOverride()方法
第一步是首先使用MeasureOverride()方法决定每个子元素希望多大的空间。每个MeasureOverride()方法的实现负责遍历子元素集合,并调用每个子元素的Measure()方法。当调用Measure()方法时,需要提供边界框——决定每个子空间最大可用空间的Size对象。在MeasureOverride()方法的最后,面板返回显示所有子元素所需的空间,并返回它们所期望的尺寸。
下面是MeasureOverride()方法的基本结构,其中没有具体的尺寸细节:
Measure()方法不返回数值。在为每个子元素调用Measure()方法之后,子元素的DesiredSize属性提供了请求的尺寸。可以在为后续子元素执行计算是(以及决定面板需要的总空间时)使用这一信息
在测量过程的结尾,布局容器必须返回它所期望的尺寸。在简单的面包中,可以通过组合每个子元素的期望尺寸计算面板所期望的尺,Measure()方法触发MeasureOverride()方法。所以如果在一个布局容器中放置另一个布局容器,当调用Measure()方法时,将会得到布局容器及其所有子元素所需要的总尺寸
2、ArrangeOverride()方法
测量完所有元素后,就可以在可用的空间中排列元素了。布局系统调用面板的ArrangeOverride()方法,而面板为每个子元素调用Arrange()方法,以高速子元素为它分配了多大的控件(Arrange()方法会触发ArrangeOverride()方法,这与Measure()方法会触发MeasureOverride()方法非常类似)
当使用Measure()方法测量条目时,传递能够定义可用空间边界的Size对象。当使用Arrange()方法放置条目时,传递能够定义条目尺寸和位置的System.Windows.Rect对象。这时,就像使用Canvas面板风格的X和Y坐标放置每个元素一样(坐标确定布局容器左上角与元素左上角之间的距离)
下面是ArrangeOverride()方法的基本结构:
理解这两个方法的最快捷方法是研究Canvas类的内部工作原理,Canvas是最简单的布局容器。为了创建自己的Canvas风格的面板,只需要简单地继承Panel类,并且添加MeasureOverride()和ArrangeOverride()方法,public class CanvasClone:System.Windows.Controls.Panel{...}
Canvas面板在他们希望的位置放置子元素,并且为子元素设置它们希望的尺寸。所以,Canvas面板不需要计算如何分割可用空间。这使得MeasureOverride()方法非常简单。为每个子元素提供无限的空间:
注意,MeasureOverride()方法返回空的Size对象。这意味着Canvas 面板根本不请求人和空间,而是由用户明确地为Canvas面板指定尺寸,或者将其放置到布局容器中进行拉伸以填充整个容器的可用空间。
下面是用于排列元素的代码: