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 ...
随机推荐
- 炉石传说 C# 开发笔记(BS上线尝试)
昨天买了一个月的1G 1核的服务器,由于不是新用户,所以没有享受到阿里的6个月免费的优惠. (阿里脑残,为什么不对于续费或者升级免费呢?) 在服务器的通讯上面已经OK了,完全绕过了ASP.NET,就是 ...
- Maven依赖Scope标签用法
在一个maven项目中,如果存在编译需要而发布不需要的jar包,可以用scope标签,值设为provided.如下: <dependency> <groupId ...
- CI框架源码阅读笔记2 一切的入口 index.php
上一节(CI框架源码阅读笔记1 - 环境准备.基本术语和框架流程)中,我们提到了CI框架的基本流程,这里再次贴出流程图,以备参考: 作为CI框架的入口文件,源码阅读,自然由此开始.在源码阅读的过程中, ...
- tomcat 5.5、6、7各版本的web-app标准
刚把上周说的公司内各工程的web.xml给统一了,顺便看了下每个tomcat版本对应的标准servlet版本,如下: The XSD version is preferred since JSP 2. ...
- java多线程-线程通信
线程通信的目标是使线程间能够互相发送信号.另一方面,线程通信使线程能够等待其他线程的信号. 通过共享对象通信 忙等待 wait(),notify()和 notifyAll() 丢失的信号 假唤醒 多线 ...
- NotSerializableException解决方法
NotSerializableException 问题描述: 想要写入对象的时候的时候回抛出NotSerializableException:类名 原因: 写入的对象没有序列化,即没有实现java.i ...
- 手机网游开发指南 - 需要多NB的技术
Agent`K 似乎在三天打鱼N天晒网.只能呵呵了,懒散的家伙. 移动互联网越来越火,其中的网络游戏更是火,熊熊大火. 作为攻城师的你,作为小投资者的你,作为满脑子创意想要实现的你,肯定在四处打听:手 ...
- 更加简洁易用——wangEditor富文本编辑器新版本发布
1. 前言 wangEditor富文本编辑器(www.wangEditor.com)从去年11月份发布,至今已经有将近10各月了.它就像一个襁褓中的小婴儿,在我的努力以及众多使用者的支持下不断摸索.成 ...
- 选中没有选中的复选框,匹配含有某个字符串的正则,json取值的两种方法,把变量定义在外面跟里面的区别
一.筛选没有选中的复选框:not("input:checked") 二.匹配有VARCHAR的字符串:".*VARCHAR.*?" 三.json取值的两种方法 ...
- 你可能不需要 jQuery!使用原生 JavaScript 进行开发
很多的 JavaScript 开发人员,包括我在内,都很喜欢 jQuery.因为它的简单,因为它有很多丰富的插件可供使用,和其它优秀的工具一样,jQuery 让我们开发人员能够更轻松的开发网站和 We ...