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#使用Process调用批处理阻塞问题
PS:又见到熟悉的C#代码了,好开心,哈哈哈.这次又跳坑了,好不容易才爬起来. 公司有自己开发的一套Submit.Compile.Publish的生命周期系统. 在Compile时,需要调用外部的 ...
- 用于PHP的Gearman Worker管理工具GearmanManager
项目地址:https://github.com/brianlmoon/GearmanManager PHP环境要求 PHP 5.5.9 POSIX extension Process Control ...
- web.xml中openEntityManagerInViewFilter的作用(转)
<filter> <filter-name>openEntityManagerInViewFilter</filter-name> <filter-class ...
- bootstrap框架禁用谷歌字体
bootstrap框架禁用谷歌字体 H5框架换字体.png
- php错误处理-错误处理
错误类型 因为错误类型整型值的巧妙设定,可以采用按位运算符 1 E_ERROR (integer) 致命的运行时错误.这类错误一般是不可恢复的情况,例如内存分配导致的问题. 导致脚本终止不再继续运行 ...
- Linux命令详解之—more命令
Linux more命令同cat命令一样,多用来查看文件内容,本文就为大家介绍下Linux more命令的用法. 更多Linux命令详情请看:Linux命令速查手册 Linux的more命令类似 ca ...
- js中对象使用
简单记录javascript中对象的使用 一.创建对象 //创建一个空对象 var o={}; //创建一个含有两个属性的对象,x.y var o2={x:12,y:'12',name:'JS'}; ...
- 【FFmpeg】Windows下FFmpeg调试
为了深入了解ffmpeg的工作原理,需要阅读源代码,调试源代码.在Windows下调试ffmpeg源码,一种方法是在MinGW+Msys环境下,利用GDB进行调试:另一种是借助Eclipse进调试,其 ...
- 【背景建模】PbModel
PbModel是基于概率模型的背景差分算法,其基本思想是像素点会因光照变化.运动物体经过产生多种颜色值,但是一段时间内,像素点处于静止状态的时间会比处于运动状态的时间长.因而一段时间内,像素点某个颜色 ...
- Monkey测试3——Monkey测试结果分析
Monkey测试结果分析 一. 初步分析方法: Monkey测试出现错误后,一般的差错步骤为以下几步: 1. 找到是monkey里面的哪个地方出错 2. 查看Monkey里面出错前的一些事件动作,并手 ...