自定义WPF布局面板

  • 格式:docx
  • 大小:48.43 KB
  • 文档页数:2

下载文档原格式

  / 2
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

WPF 学习 如何自定义 WPF 布局面板
WPF 拥有很多布局面板,比如 Grid,StackPanel 等,这让我们的界面布局更加的灵活,但 也许这些面板并不能完全满足你的需求,这时你需要自定义面板 自定义面板来满足你的布局要求。 自定义面板 1,面板布局是如何实现的 面板布局是如何实现的 WPF 布局引擎采用了一种递归的方式来实现控件及其子控件的布局,大致过程是这样的:要 实现控件 A 的布局,那么先要实现 A 的子控件 a1,a2,a3...的布局,要实现 a1 的布局,那么得实现 a1 的子控件 a11,a12,a13...的布局,如此循环,然后但子控件的布局完成后,在完成父控件的布局, 最后递归回去,递归结束,布局才算完成. 控件的最终大小和位置是由该控件和父控件相磋商来完成的,父控件先给出其能给予子控件 的力所能及的布局空间,子控件在反馈给父控件一个自己的期望值,父控件最后根据自己所拥有 的空间大小与子控件的期望值分配一定的空间给子控件并返回自己的大小.这一系列过程是通过 重写面板的 MeasureOverride 和 ArrangeOverride 方法来完成的. 2,Size MeasureOverride(Size availableSize)方法 方法 该方法为布局中控件所需要的空间大小进行评估。 参考如下代码: 以下是引用片段: 以下是引用片段: protected override Size MeasureOverride(Size availableSize) { Size childrenSize = new Size(0, 0); foreach (UIElement child in this.Children) { child.Measure(new Size(Double.PositiveInfinity,Double.PositiveInfinity)); childrenSize.Width += child.DesiredSize.Width; childrenSize.Height += child.DesiredSize.Height; } return childrenSize; } 在 MeasureOverride 阶段我们对面板中的每个 Child 调用了其 Measure(Size sz)方法,该方 法的作用是父控件告诉子控件其预计要分配给子控件的空间大小,对 Child 调用了该 Measure 方 法后,子控件会在其内部给父控件一个回应以便告诉父控件它所期望的大小,而子控件的该期望 值便保存在其 child.DesiredSize 中.如果 Measure 方法中传入的是正无穷大(new Size(Double.PositiveInfinity,Double.PositiveInfinity))时,相当于父控件在对子控件说"尽管说出 你所需要的大小吧,如果可以的话全世界都可以给你". MeasureOverrice 方法中的 availableSize 参数正是其父控件(你编写的面板控件以后在实际 使用时其父控件)对其调用 Measure 方法时传入的值(减去一些边界值,比如要减掉 Margin 等) MeasureOverride 方法的返回值正是其告诉其父控件的期望值,即是其父控件(你编写的面板 控件以后在实际使用时其父控件)对其调用 Measure 方法后,其 DesiredSize 值 注意:作为父控件,你可以很慈爱地仅可能地满足子控件的需要(尽管不一定有这能力),所以 注意 可以在对子控件调用 Measure 方法时传入一个正无穷大的尺寸,但作为子控件,你不能贪婪地向 父控件索要正无穷大的空间,所以我们不能将正无穷大作为 MeasureOverride 方法的返回值,也 不能直接将该方法的 availableSize 参数作为返回值(因为你的父控件有可能将正无穷大作为该参 数传递给你)

3,Size ArrangeOverride(Size finalSize)方法 方法 该方法作用在于为面板子控件提供布局空间即排列子控件并返回自身大小 参考下面的代码: 以下是引用片段: 以下是引用片段: 用片段 protected override Size ArrangeOverride(Size finalSize) { Point childPos = new Point(0, 0); foreach (UIElement child in this.Children) { child.Arrange(new Rect(childPos, new Size(child.DesiredSize.Width, finalSize.Height))) ; childPos.X += child.RenderSize.Width; } return finalSize; } 该方法对每个 Child 调用 Arrange 方法,Arrange 方法中传入的 Rect 结构告诉子控件其被安 排在那个空间内进行布局,然后子元素会根据自己得到的空间以及自己的对齐属性 (XXXAlignment)进行放置,放置完成后子控件的大小等便得到了确定,而该值便存放在子控件的 RenderSize 中(即是 ActualWidth 与 ActualHeight). 控件本身也可以根据子控件占用的实际空间大小来决定自己的大小,也可以直接将得到的空 间大小(即是 ArrangeOverride 方法中的 finalSize 参数)作为自己的最终大小返回 ArrangeOverride 方法中的 finalSize 参数是该控件的父控件(你编写的面板控件以后在实际 使用时其父控件)在对该控件调用 Arrange 方法时传入的 Rect 的大小,正如该控件对其子控件调 用 Arrange 方法一样. 注意:Child 的 Arrange 方法只是给定一个空间让子控件在此空间内进行摆放,该空间并没有 注意 决定子控件的具体位置和大小,这还得取决于子控件的其它属性,比如 HorizontalAlignment 与 VerticalAlignment 等. 在 Arrange 期间,系统会自动进行对齐(Alignment)操作。 下图是自定义的面板 MyStackPanel,其比 WPF 内置的 StackPanel 多了两个方向上的布局 ("从右到左"与"从下到上")