Welcome

首页 / 软件开发 / .NET编程技术 / Windows 8 Store Apps学习(17) 控件基础: Measure等

Windows 8 Store Apps学习(17) 控件基础: Measure等2013-12-04 cnblogs webabcd控件基础: Measure, Arrange, GeneralTransform, Visua

介绍

重新想象 Windows 8 Store Apps 之 控件基础

Measure() 和 Arrange() - xaml 的 layout 系统

GeneralTransform - 通过 UIElement.TransformToVisual() 获取元素的位置信息

VisualTree - 可视树

示例

1、演示 xaml 的 layout 系统

Controls/Basic/MeasureArrange.xaml

<Pagex:Class="XamlDemo.Controls.Basic.MeasureArrange"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="using:XamlDemo.Controls.Basic"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"mc:Ignorable="d"><Grid Background="Transparent"><local:MyStackPanel Margin="120 0 0 0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="200" Height="200"><TextBlock Text="我是文本" Width="100" Height="100" /><Button Content="我是按钮" Width="150" Height="150" /></local:MyStackPanel></Grid></Page>
Controls/Basic/MeasureArrange.xaml.cs

/* * 演示 Layout 系统 ** win8 xaml 的 layout 就是一个递归系统,本 demo 就递归的一个过程做说明(步骤顺序参见代码注释中的序号) */using System;using System.Diagnostics;using Windows.Foundation;using Windows.UI.Xaml;using Windows.UI.Xaml.Controls;namespace XamlDemo.Controls.Basic{public sealed partial class MeasureArrange : Page{public MeasureArrange(){this.InitializeComponent();}}public class MyStackPanel : StackPanel{// 1、首先爸爸知道自己能够提供的尺寸 availableSize,然后告诉儿子们protected override Size MeasureOverride(Size availableSize){// 2、儿子们收到 availableSize 后,又结合了自身的实际情况,然后告诉爸爸儿子们所期望的尺寸 desiredSizeSize desiredSize = base.MeasureOverride(availableSize);Debug.WriteLine("availableSize: " + availableSize.ToString());Debug.WriteLine("desiredSize: " + desiredSize.ToString());return desiredSize;// 以下是自定义的 Measure 逻辑,供参考/*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;*/}// 3、爸爸收到儿子们的反馈后,告诉儿子们自己最终提供的尺寸 finalSizeprotected override Size ArrangeOverride(Size finalSize){// 4、儿子们根据 finalSize 安排各自的位置,然后爸爸的呈现尺寸也就确定了 renderSizeSize renderSize = base.ArrangeOverride(finalSize);Debug.WriteLine("finalSize: " + finalSize.ToString());Debug.WriteLine("renderSize: " + renderSize.ToString());return renderSize;// 以下是自定义的 Arrange 逻辑,供参考/*Point childPos = new Point(0, 0);foreach (UIElement child in this.Children){child.Arrange(new Rect(childPos, new Size(child.DesiredSize.Width, child.DesiredSize.Height)));childPos.Y += child.RenderSize.Height;}return finalSize;*/}}}/* * 输出结果: * availableSize: 200,200 * desiredSize: 150,250 * finalSize: 200,250 * renderSize: 200,250*//* * 注: * UIElement * 调用 Measure() 方法后会更新 DesiredSize 属性 * 调用 Arrange() 方法后会更新 RenderSize 属性 * UpdateLayout() - 强制 layout 递归更新 ** FrameworkElement - 继承自 UIElement * MeasureOverride() - 重写 Measure() * ArrangeOverride() - 重写 Arrange() * ActualWidth 和 ActualHeight 来自 RenderSize,每次 UpdateLayout() 后都会被更新 */