WPF学习之路(十一)布局(续)
布局实际上是一个Slot模型,其中每个父对象分配给子对象一个Slot,子对象可以自由占用Slot中的空间,通过Margin\VerticalAlignment\HorizontalAlignment控制
实例
<Border Background="LightBlue" BorderBrush="Black" BorderThickness="" CornerRadius="" Padding="">
<StackPanel Name="SP1" Background="White">
<TextBlock FontSize="" HorizontalAlignment="Center" Margin="0,0,0,15" Text="StackPanel1"></TextBlock>
<Border BorderThickness="" BorderBrush="Black">
<Button Margin="5,10,15,20">Normal</Button>
</Border>
<Border BorderThickness="" BorderBrush="Black">
<Button Margin="5,10,15,20" HorizontalAlignment="Left">
<Button.LayoutTransform>
<RotateTransform Angle="" />
</Button.LayoutTransform>
Left</Button>
</Border>
<Border BorderThickness="" BorderBrush="Black">
<Button Margin="5,10,15,20" HorizontalAlignment="Right">
<Button.LayoutTransform>
<RotateTransform Angle="" />
</Button.LayoutTransform>
Right</Button>
</Border>
<Border BorderThickness="" BorderBrush="Black">
<Button Margin="5,10,15,20" HorizontalAlignment="Center">
<Button.LayoutTransform>
<RotateTransform Angle="" />
</Button.LayoutTransform>
Center</Button>
</Border>
<Border BorderThickness="" BorderBrush="Black">
<Button Margin="5,10,15,20" >
<Button.LayoutTransform>
<RotateTransform Angle="" />
</Button.LayoutTransform>
LayoutTransform
</Button>
</Border>
<Border BorderThickness="" BorderBrush="Black">
<Button Margin="5,10,15,20" >
<Button.RenderTransform>
<RotateTransform Angle="" />
</Button.RenderTransform>
RenderTransform
</Button>
</Border>
</StackPanel>
</Border>
注意LayoutTransform和RenderTransform的区别

自定义布局
确定空间最佳尺寸经历两个阶段,1.测量,父元素询问子元素期望的尺寸,来确定自身尺寸 2.布置,父元素告知子元素的位置
具体实现为以下两个重载函数
protected override Size ArrangeOverride(Size arrangeBounds);
protected override Size MeasureOverride(Size constraint);
自定义CustomPanel
public class CustomPanel : Panel
{
public CustomPanel()
: base()
{
} protected override Size MeasureOverride(Size availableSize)
{
double maxChildWidth = 0.0;
double maxChildHeight = 0.0;
foreach (UIElement child in InternalChildren)
{
child.Measure(availableSize);
maxChildWidth = Math.Max(child.DesiredSize.Width, maxChildWidth);
maxChildHeight = Math.Max(child.DesiredSize.Height, maxChildHeight);
} double idealCircumference = maxChildWidth * InternalChildren.Count;
double idealRadius = idealCircumference / (Math.PI * ) + maxChildHeight; Size desired = new Size(idealRadius * , idealRadius * ); if (!double.IsInfinity(availableSize.Width))
{
if (availableSize.Width < desired.Width)
desired.Width = availableSize.Width;
}
if (!double.IsInfinity(availableSize.Height))
{
if (availableSize.Height < desired.Height)
desired.Height = availableSize.Height;
} return desired;
} protected override Size ArrangeOverride(Size finalSize)
{
Rect layoutRect;
if (finalSize.Width > finalSize.Height)
{
layoutRect = new Rect((finalSize.Width - finalSize.Height) / , , finalSize.Height, finalSize.Height);
}
else
{
layoutRect = new Rect((finalSize.Height - finalSize.Width) / , , finalSize.Width, finalSize.Width);
} double angleInc = / InternalChildren.Count;
double angle = ;
foreach (UIElement child in InternalChildren)
{
Point childLocation = new Point(layoutRect.Left + (layoutRect.Width - child.DesiredSize.Width) / , layoutRect.Top);
child.RenderTransform = new RotateTransform(angle, child.DesiredSize.Width / , finalSize.Height / - layoutRect.Top);
angle += angleInc;
child.Arrange(new Rect(childLocation, child.DesiredSize));
} return finalSize;
}
}
<Page x:Class="Alex_WPFAPPDemo09.DemoPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Alex_WPFAPPDemo09"
mc:Ignorable="d"
d:DesignHeight="" d:DesignWidth=""
Title="DemoPage"> <Grid Margin="">
<local:CustomPanel>
<Button Content="" MinWidth="" />
<Button Content="" MinWidth="" />
<Button Content="" MinWidth="" />
<Button Content="" MinWidth="" />
<Button Content="" MinWidth="" />
<Button Content="" MinWidth="" />
<Button Content="" MinWidth="" />
</local:CustomPanel>
</Grid>
</Page>

To be continue...
WPF学习之路(十一)布局(续)的更多相关文章
- WPF学习之路初识
WPF学习之路初识 WPF 介绍 .NET Framework 4 .NET Framework 3.5 .NET Framework 3.0 Windows Presentation Found ...
- WPF学习(一)--布局控件简介
WPF的4种基本布局介绍 1.Grid的布局 这个就没啥特别好说的,其实,基本上复杂的布局,都需要用到Grid. 主要就是对行和列进行进行设置和定义. 1.行表格 列表格: 包含行和列的表格 2.St ...
- WPF学习(3)布局
今天我们来说说WPF的布局.我们知道WinForm的布局主要是采用基于坐标的方式,当窗口内容发生变化时,里面的控件不会随之动态调整,这就造成了一个很不好的用户体验.而WPF为了避免这个缺点,采用了基于 ...
- 【WPF学习】第二十一章 特殊容器
内容控件不仅包括基本控件,如标签.按钮以及工具提示:它们还包含特殊容器,这些容器可用于构造用户界面中比较大的部分区域. 首先介绍ScrollViewer控件,该控件直接继承自ContentContro ...
- WPF学习之路(十一)布局
布局 Canvas 基本面板,传统布局方式,支持与设备无关的坐标定位元素 <Border BorderThickness="> <Canvas> <Button ...
- WPF学习之路(二) XAML(续)
属性 简单属性 前面用到的Width/Height都是简单属性,其赋值一定要放到双引号里 XAML解析器会根据属性的类型执行隐式转换 与C#的区别 SolidBrush.Color = Colors. ...
- WPF学习之路(九)导航和页面(续)
生命周期 如果Page1成功导航到Page2,首先会触发NavigationService的Navigating事件,标识导航开始.随后创建Page2对象,并且触发NavigationProgress ...
- WPF学习之路(七)应用程序和窗口(续)
窗口的生命周期 WPF中一个Window类代表一个窗口 一个的窗口的生命周期也有好几个阶段: 1.构造器被调用 2.Window.Initialized事件被触发 3.Window.Activated ...
- WPF学习之路(五) 实例:写字板(续)
WordPad 2.0 上一期实现了一虽然建议但是功能比较全面的Wordpad程序,但是程序代码略显繁琐,这一期更新改进版. MainWindows.xaml 添加 <Window.Comman ...
随机推荐
- (二)NetHelper
[转]http://blog.csdn.net/dingxiaowei2013/article/details/8113454 using System; using System.Text; usi ...
- 点击一个div隐藏另一个div
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Java递归列出所有文件和文件夹
package file_op; import java.io.File; public class file_list { static int n =0; /** * @param args */ ...
- Firemonkey 载入 Style 皮肤 (*.fsf 二进制文件) 速度测试
说明:Firemonkey 可以换肤是一大亮点,但使用它必须要付出一点代价,就是需要一点载入的时间,下面以 *.fsf 二进制文件来做载入测试,有兴趣可以参考看看. 开发:XE8 for iOS 皮肤 ...
- 纯灌水Linus主义
卖桃君重新整理了Linus的相关故事,在此摘选对自己有触动的内容. 关于生命的意义,李纳斯的解释是,有三件事具有生命的意义.它们是你生活当中所有事情的动机.第一是生存,第二是社会秩序,第三是娱乐.生活 ...
- Centos压缩与打包
这个虽然是基础知识,但是有些东西就是这样,久了没用,就会忘记,而且之前有一个坏习惯就是不喜欢做笔记,以后学习了行东西一定要记录在博客,这样以后自己也能时不时的查看一下. 言归正传,在计算机的世界中,数 ...
- 第 1 章 HTML5 概述
学习要点: 1.HTML5 的历史 2.HTML5 的功能 3.HTML5 的特点 4.课程学习问题 主讲教师:李炎恢 HTML5 是继 HTML4.01 和 XHTML1.0 之后的超文本标记语言的 ...
- 使用QRCode简单生成二维码
// // ViewController.m // 二维码 // // Created by 123 on 16/9/4. // Copyright © 2016年 彭洪. All right ...
- Java主要知识结构
Java基础(建议看java编程规范): Java语言基础:数据类型,命名规则,权限控制符,注释 操作符:算术操作符,逻辑操作符,关系操作符,移位操作符,按位操作符 流程控制 数组 字符串 Java高 ...
- 关于JAVA数据储存
关于JAVA数据储存: 在JAVA中,有六个不同的地方可以存储数据: 1. 寄存器(register) 这是最快的存储区,因为它位于不同于其他存储区的地方--处理器内部.但是寄存器的数量极其有限,所以 ...