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 ...
随机推荐
- Nhibernate的第一个实例
第一个NhIbernate程序 1.目的: a) 链接到oracle数据库 b) 增删改 c) 基本查询.sql查询 d) 视图查询 e) 使用存储过程 f) 多表查询.级联查询 g) 级联增删改 2 ...
- Calling startActivity() from outside of an Activity
在Activity中使用startActivity()方法不会有任何限制,因为Activity重载了Context的startActivity()方法.但是如果是在其他地方(如Widget或Servi ...
- hibernate------java-delete-insert-update
**************************************************************************************************** ...
- 基于Erlang VM的函数式编程语言Elixir
Elixir官网:http://elixir-lang.org/ Elixir是一种函数式动态语言,用于构建可伸缩.易维护的应用程序. Elixir是基于Erlang VM的,其广为人知的特点是运行低 ...
- 禅道PMS兼容redmine用户认证接口
项目地址:https://github.com/web3d/zentao-redmine-userauth zentao-redmine-userauth 做了一个基本的用户认证接口,兼容redmin ...
- SNAT,是源地址转换,其作用是将ip数据包的源地址转换成另外一个地址
SNAT,可能有人觉得奇怪,好好的为什么要进行ip地址转换啊,为了弄懂这个问题,我们要看一下局域网用户上公网的原理,假设内网主机A(192.168.2.8)要和外网主机B(61.132.62.131) ...
- 解决 WinXP下 libcurl.dll 无法定位程序输入点GetTickCount64问题
1. 问题描述 用 IDA 打开libcurl.dll 可以在导入表看到对 GetTickCount64的引用,在 xp 的kernel32.dll中没有 GetTickCount64, 所以会出现 ...
- <welcome-file-list>标签的控制作用以及在springmvc中此标签的的配置方式
我们在写安全性较高的网站时必然会对网站的入口进行限制, 而在这其中其关键作用的就是网站的根目录下WEB-INF中的web.xml中<welcome-file-list> <welc ...
- something
var colors=['red','green','yellow']; console.log(colors)//['red','green','yellow'] console.log(color ...
- Clipboard.js – 现代方式实现复制文本到剪贴板
复制文本到剪贴板应该并不难,目前已经有很成熟的 Flash 方法.但是 Flash 已经在很多场合不适用了,特别是随着 HTML5 技术的发展.今天推荐的这个 Clipboard.js 库不依赖 Fl ...