[WP8.1UI控件编程]Windows Phone自定义布局规则

3.2 自定义布局规则

    上一节介绍了Windows Phone的系统布局面板和布局系统的相关原理,那么系统的布局面板并不一定会满足所有的你想要实现的布局规律,如果有一些特殊的布局规律,系统的布局面板是不支持,这时候就需要去自定义实现一个布局面板,在自定义的布局面板里面封装布局规律的逻辑。那么我们这一节从一个实际的需求出发,来实现一个自定义规律的布局面板。我们这一小节要实现的布局规律是把布局面板里面的子元素,按照圆形的排列规则进行排列,下面我们来看下这个例子的详细实现过程。

3.2.1 创建布局类

    在Windows Phone要实现类似Grid、StackPanel的自定义布局规则的面板,首先要做的事情是要创建一个自定义的布局类。所有的布局面板都需要从Panel类派生,自定义实现其测量和排列的过程。Panel类中的Children属性表示是布局面板里面的子对象,测量和排列的过程中需要根据Children属性来获取面板中所有的子对象,然后再根据相关的规律对这些子对象进行测量和排列。

    如果我们的布局类需要外面传递进来一些特殊的参数,那么就需要我们在布局类里面去实现相关的属性。当然像Heigh、Width等这些Panel类原本就支持的属性我们就无需再去定义,如我们在这个例子里面要实现的圆形布局,这时候是需要一个圆形的半径大小的,这个半径的大小就可以作为一个属性让外面把数值传递进来,然后布局类再根据这个半径的大小来进行处理对子对象的测量和排列。需要注意的是,自定义的半径属性发生改变的时候,需要调用InvalidateArrange方法重新触发布局的排列过程,否则修改半径后将不会起到任何作用。

代码清单3-2自定义布局规则(源代码:第3章\Examples_3_2)

    下面我们来看一下,自定义的CirclePanel类:

    public class CirclePanel : Panel{//自定义的半径变量private double _radius = 0;public CirclePanel(){}//注册半径依赖属性//"Radius" 表示半径属性的名称// typeof(double) 表示半径属性的类型// typeof(CirclePanel) 表示半径属性的归属者类型// new PropertyMetadata(0.0, OnRadiusPropertyChanged)) 表示半径属性的元数据实例,0.0是默认值,OnRadiusPropertyChanged是属性改变的事件public static readonly DependencyProperty RadiusProperty = DependencyProperty.RegisterAttached("Radius",typeof(double), typeof(CirclePanel),new PropertyMetadata(0.0, OnRadiusPropertyChanged));//定义半径属性public double Radius{get { return (double)GetValue(RadiusProperty); }set { SetValue(RadiusProperty, value); }}//实现半径属性改变事件private static void OnRadiusPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e){//获取触发属性改变的CirclePanel对象CirclePanel target = (CirclePanel)obj;//获取传递进来的最新的值,并赋值给半径变量target._radius = (double)e.NewValue;//使排列状态失效,进行重新排列
            target.InvalidateArrange();}//重载基类的MeasureOverride方法protected override Size MeasureOverride(Size availableSize){//处理测量子对象的逻辑return availableSize;}//重载基类的ArrangeOverride方法protected override Size ArrangeOverride(Size finalSize){//处理排列子对象的逻辑return finalSize;}}

3.2.2 实现测量过程

    测量的过程是在重载的MeasureOverride方法上实现,在MeasureOverride方法上需要做的第一件事情就是要把所有的子对象都遍历一次,调用其Measure方法来测量子对象的大小。然后在测量的过程中可以获取到子对象测量出来的宽度高度,我们可以根据这些信息来给自定义的面板分配其大小。

    protected override Size MeasureOverride(Size availableSize){//最大的宽度的变量double maxElementWidth = 0;//遍历所有的子对象,并调用子对象的Measure方法进行测量,取出最大的宽度的子对象foreach (UIElement child in Children){//测量子对象
            child.Measure(availableSize);maxElementWidth = Math.Max(child.DesiredSize.Width, maxElementWidth);}//两个半径的大小和最大的宽度的两倍最为面板的宽度double panelWidth = 2 * this.Radius + 2 * maxElementWidth;//取面板的所分配的高度宽度和计算出来的宽度的最小值最为面板的实际大小double width = Math.Min(panelWidth, availableSize.Width);double heigh = Math.Min(panelWidth, availableSize.Height);return new Size(width, heigh);}

3.2.3 实现排列过程

    排列的过程是在重载的ArrangeOverride方法上实现,在ArrangeOverride方法上通过相关的规则把子对象一一地进行排列。我们在例子里面要实现的是把子对象按照一个固定的圆形进行排列,所以在ArrangeOverride方法上需要计算每个子对象所占的角度大小,通过角度计算子对象在面板中的坐标,然后按照一定的角度对子对象进行旋转来适应圆形的布局。排列原理图如图3.7所示,实现代码如下。

    protected override Size ArrangeOverride(Size finalSize){//当前的角度,从0开始排列double degree = 0;//计算每个子对象所占用的角度大小double degreeStep = (double)360 / this.Children.Count;//计算double mX = this.DesiredSize.Width / 2;double mY = this.DesiredSize.Height / 2;//遍历所有的子对象进行排列foreach (UIElement child in Children){//把角度转换为弧度单位double angle = Math.PI * degree / 180.0;//根据弧度计算出圆弧上的x,y的坐标值double x = Math.Cos(angle) * this._radius;double y = Math.Sin(angle) * this._radius;//使用变换效果让控件旋转角度degreeRotateTransform rotateTransform = new RotateTransform();rotateTransform.Angle = degree;rotateTransform.CenterX = 0;rotateTransform.CenterY = 0;child.RenderTransform = rotateTransform;//排列子对象child.Arrange(new Rect(mX + x, mY + y, child.DesiredSize.Width, child.DesiredSize.Height));//角度递增degree += degreeStep;}return finalSize;}

3.2.4 应用布局规则

    在上面我们已经把自定义的圆形布局控件实现了,现在要在XAML页面上应用该布局面板来进行布局。在这个例子里面,我们还通过一个Slider控件来动态改变布局面板的半径大小,来观察布局的变化。

    首先我们在XAML页面上引入布局面板所在的空间,如下所示:

    xmlns:local="clr-namespace:CustomPanelDemo"

    然后在XAML页面上运用自定义的圆形布局控件,并且通过Slider控件的ValueChanged来动态给圆形布局控件的半径赋值。代码如下:

MainPage.xaml文件主要代码
------------------------------------------------------------------------------------------------------------------<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"><Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition Height="Auto"/></Grid.RowDefinitions><Slider Grid.Row="0" Value="5" ValueChanged="Slider_ValueChanged_1"></Slider><local:CirclePanel x:Name="circlePanel" Radius="50" Grid.Row="1"  HorizontalAlignment="Center" VerticalAlignment="Center"><TextBlock>Start here</TextBlock><TextBlock>TextBlock 1</TextBlock><TextBlock>TextBlock 2</TextBlock><TextBlock>TextBlock 3</TextBlock><TextBlock>TextBlock 4</TextBlock><TextBlock>TextBlock 5</TextBlock><TextBlock>TextBlock 6</TextBlock><TextBlock>TextBlock 7</TextBlock></local:CirclePanel></Grid>
MainPage.xaml.cs文件主要代码
------------------------------------------------------------------------------------------------------------------private void Slider_ValueChanged_1(object sender, RangeBaseValueChangedEventArgs e){if (circlePanel != null){ circlePanel.Radius = e.NewValue * 10;}}

本文来源于《深入理解Windows Phone 8.1 UI控件编程》

源代码下载:http://vdisk.weibo.com/s/zt_pyrfNHoezI

欢迎关注我的微博@WP林政

WP8.1技术交流群:372552293

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/299663.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

聊聊编程语言的选择

我适合学什么编程语言呢&#xff1f;大家好&#xff0c;我是鱼皮&#xff0c;今天聊聊编程语言的选择问题&#xff0c;通过对 10 主流编程语言的特点、优劣、应用场景、发展前景等简单分析&#xff0c;希望帮还在迷茫的小伙伴们选择最适合自己的语言去学习。编程语言选择本文大…

IIS6文件权限不对触发了Windows身份认证问题解决方法

今天在iis上调试程序的时候突然发现需要登录: 通过csdn提问得知可能是权限设置有问题于是设置了下internet来宾用户: 结果问题没有解决.后来想想应该不是问题,因为我在自己机器上调试用的是Everyone权限,应该都可以访问. 于是我又去用户管理中重置internet来宾用户密码: 重置In…

C++ Exercises(十五)--排序算法的简单实现

structNode {//队列结点 int data; struct Node* pNext;};classCQueue{//队列类(带头结点&#xff09;public: CQueue(void); ~CQueue(void); bool isEmpty()const;//是否为空 void EnQueue(int num);//入队列 int DeQueue();//出队列 int Front()cons…

朋友圈终于能斗表情包了,会发表情包您就多发点!

全世界只有3.14 % 的人关注了青少年数学之旅今日&#xff0c;微信ios端更新至7.0.9版本&#xff0c;又上了一次微博热搜。版本新增了朋友圈图片评论功能&#xff0c;动态图、静态图均可&#xff0c;点击图片评论即可查看大图&#xff0c;评论图片同步聊天表情包库。各路网友收到…

EF Core 异步编程注意要点

????欢迎点赞 &#xff1a;???? 收藏 ⭐留言 ???? 如有错误敬请指正&#xff0c;赐人玫瑰&#xff0c;手留余香&#xff01;????本文作者&#xff1a;由webmote 原创&#xff0c;????作者格言&#xff1a;生活在于折腾&#xff0c;当你不折腾生活时&#x…

看电影的第一大禁忌 | 今日最佳

全世界只有3.14 % 的人关注了青少年数学之旅&#xff08;图源网络&#xff0c;侵权删&#xff09;

求职华为,被问观察者模式,从没有这种体验!!!

求职华为&#xff0c;被问观察者模式&#xff0c;从没有这种体验&#xff01;&#xff01;&#xff01;模式的定义与特点模式的结构与实现1. 模式的结构2. 模式的实现模式的应用实例模式的应用场景模式的扩展1. Observable类2. Observer 接口[ 观察者模式可以说是非常贴近我们…

SQL2005的配置

最近迷上c#&#xff0c;下午装好了SQL server management studio Express 附加经典的northwind数据库 然后用下面一段代码测试 1usingSystem;2usingSystem.Collections.Generic;3usingSystem.Text;4usingSystem.Data;5usingSystem.Data.Sql;6usingSystem.Data.SqlClient;78name…

为什么应该用record来定义DTO(续)

前言上次&#xff0c;我们介绍了因为DTO的“不变性”&#xff0c;应该用record来定义DTO。今天&#xff0c;我们来说明用record来定义DTO的另一个好处。问题首先&#xff0c;我们实现一个Controler&#xff0c;代码如下:[ApiController] [Route("[controller]")] pub…

资料分享 | 数学建模竞赛备战大全

全世界只有3.14 % 的人关注了青少年数学之旅目前针对数学建模的认知&#xff0c;绝大部分人还停留在数学建模竞赛阶段&#xff0c;并不知道数学建模是数据领域非常重要的一种方法。数学建模涉及的内容广泛&#xff0c;比如碎纸片问题中所涉及的图像识别及神经网络、小区开放问题…

初级Java开发工程师!绝密文档,面试手册全面突击!!!秋招已经到来

这里我要明说一下&#xff0c;不是Java初级和学习Java的千万不要乱看&#xff0c;否则~~~~ 你会怀疑人生&#xff0c;因为会浪费你时间啊&#xff01;&#xff01;&#xff01; 本次考点是Java初级开发工程师面试必备的一些东西!!! 1、数据类型 基本类型 byte/8、short/16、…

数学2600年,欧拉凭什么能当上“大王”?

全世界只有3.14 % 的人关注了青少年数学之旅何为数学&#xff1f;♠音乐家说&#xff0c;数学是世界上最和谐动听的音符♥植物学家说&#xff0c;世界上没有比数学更美的花朵♣美学家说&#xff0c;哪里有数学&#xff0c;哪里才有真正的美♦哲学家说&#xff0c;世界什么都在变…

NET流行高性能JSON框架-Json.NET

在日常编程中经常会使用到Json来进行数据的交互好在.Net平台下有很多开源的Json库使得我们能够比较轻松快速的处理各种复杂的Json&#xff0c;其中Newtonsoft库是NET的流行高性能JSON框架特性工具VS2010Newtonsoft库从NuGet下载合适的Newtonsoft.Json库1.在你需要引用Newtosoft…

Scribefire发CSDN博客

历史在非常久非常久曾经&#xff0c;CSDN是支持外部工具来写文章的&#xff0c;但是在还有一个非常久非常久曾经就不行了。突然看到CSDN有能够用外部工具来写博客了&#xff08;CSDN的公告&#xff09;&#xff0c;一直以来都纠结这个问题&#xff0c;CSDN的编辑器不好用&#…

今日笔记!——分析Java应用性能

1 问题描述 因产品架构的复杂性&#xff0c;可能会导致性能问题的因素有很多。根据部署架构&#xff0c;大致的可以分为应用端瓶颈、数据库端瓶颈、环境瓶颈三大类。可以根据瓶颈的不同部位&#xff0c;选择相应的跟踪工具进行跟踪分析。 应用层面瓶颈大致有如下两类&#xf…

除了PS,还有它可以轻松实现图像处理!

全世界只有3.14 % 的人关注了青少年数学之旅在我们生活中&#xff0c;常见的图像处理软件有Adobe Photoshop、Adobe Illustrator等。然而&#xff0c;并非只有软件才能实现图像处理&#xff0c;通过编程手段也是能实现的&#xff01;今天&#xff0c;小天将要带着大家走进计算机…

微服务并不能解决你的烂代码问题

点击上方蓝字关注我们“微服务并不能解决你的烂代码问题很久以来&#xff0c;软件的交付质量一直是一个大家比较关心的问题&#xff0c;而程序员和架构师也一直在极力寻找一种更好的方式来构建应用系统。随着互联网爆炸式的增长&#xff0c;对于系统的交付速度和质量的要求也日…

protobuf在java应用中通过反射动态创建对象

2019独角兽企业重金招聘Python工程师标准>>> ---恢复内容开始--- 最近编写一个游戏用到protobuf数据格式进行前后台传输&#xff0c;苦于protobuf接受客户端的数据时是需要数据类型的如xxx.parseForm(...),这样就要求服务器在接受客户端请求时必须知道客户端传递的数…

黑科技轮胎:有能发电的,脑洞简直不要太大...

全世界只有3.14 % 的人关注了青少年数学之旅人类历史上的很多伟大发明&#xff0c;都是由脑洞产生的&#xff0c;这样那样&#xff0c;然后问题就解决了&#xff0c;过程很复杂&#xff0c;却又很简单&#xff0c;甚至有时候&#xff0c;是一种很奇葩的方式。在漫长的历史进程中…

VS 2019 16.11正式发布 | 新功能(Hot Reload 热重载)试用

VS 2019 16.11VS 2019 16.11已于2021.8.10正式发布。&#xff08;https://devblogs.microsoft.com/visualstudio/visual-studio-16-11/&#xff09;这个版本主要包括以下内容&#xff1a;Visual Studio中的Git工具体验改进支持.NET应用程序的Hot Reload&#xff08;热重载&…