Windows Phone开发手记-WinRT下自定义圆形ItemsControl

这里的ItemsControl指的是Xaml里的集合控件,包括ListView,GridView等,此篇博客主要参考MSDN Blog的一篇文章,具体出处为:http://blogs.msdn.com/b/mim/archive/2013/04/16/winrt-create-a-custom-itemspanel-for-an-itemscontrol.aspx ,同时做了对Windows Phone的一些修改和适配。

首先,正常的GridView,和ListView的样式我就不在这里列出了,今天我们重点谈的就是如何实现一个圆形布局的ListView/Gridview。

自定义圆形ItemsControl

      

Windows Phone 8.1                                                                                                        Windows

这里我填充的Item只是简单的Image,但是并不妨碍其实现效果,这样的布局完全可以带来更惊艳的交互体验。

同时如原文所说这里提供的源码只是实现基本布局,并未提供更多的动画,手势,交互等功能,大家可以自行填充。

为了实现自定义的布局,我们需要自定义ItemsPanel来替换ItemsControl的模版,我们自定义的ItemsPanel必须继承于Panel类。

下面我们需要重写以下两个方法 :

  1. MeasureOverride :使用MeasureOverride方法来报告你所需空间的数量
  2. ArrangeOverride : 使用ArrangeOverride方法在你的ItemsPanel中真实的布局Item
//CircleItemsPanel.csusing System;
using Windows.Foundation;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml;

namespace CustomItemsPanel
{
    public class CircleItemsPanel :Panel
    {
        public double Radius {
            get {
                return (Double)GetValue(RadiusProperty);
            }
            set {
                SetValue(RadiusProperty, value);
            } }
        public static readonly DependencyProperty RadiusProperty = DependencyProperty.Register(
            "Radius", typeof(Double),typeof(CircleItemsPanel),new PropertyMetadata(100d,RadiusCallBack));

        private static void RadiusCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var radialPanel = (CircleItemsPanel)d;
            radialPanel.InvalidateArrange();
        }

        protected override Size MeasureOverride(Size availableSize)
        {
            var s= base.MeasureOverride(availableSize);
            foreach (var element in this.Children)
            {
                element.Measure(availableSize);
            }
            return s;
        }
        protected override Size ArrangeOverride(Size finalSize)
        {
            this.Clip = new RectangleGeometry {Rect=new Rect (0,0,finalSize.Width,finalSize.Height) };
            var i = 0;
            var degreesOffset = 360.0 / this.Children.Count;
            foreach(var elemet in this.Children)
            {
                var centerX = elemet.DesiredSize.Width / 2.0;
                var centerY = elemet.DesiredSize.Height / 2.0;
                var degreesAngle = degreesOffset * i++;
                var transform = new RotateTransform { CenterX=centerX,CenterY=centerY,Angle=degreesAngle };
                elemet.RenderTransform = transform;
                var radianAngle = (Math.PI * degreesAngle) / 180.0;
                var x = this.Radius * Math.Cos(radianAngle);
                var y = this.Radius * Math.Sin(radianAngle);
                var rectX = x + finalSize.Width / 2 - centerX;
                var rectY = y + finalSize.Height / 2 - centerY;
                elemet.Arrange(new Rect(rectX,rectY,elemet.DesiredSize.Width,elemet.DesiredSize.Height));
            }
            return finalSize;
        }
    }
}

至于里面数学知识的应用我就不细说,我大天朝的基础教育还是杠杠滴,贴张图大家就会明白的。

在Xaml中使用我们的圆形Panel,到此就大功告成啦。

<Page
    x:Class="CustomItemsPsnnel.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:CustomItemsPsnnel"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"

    DataContext="{Binding Path=Main, Source={StaticResource Locator}}"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid>
        <TextBlock HorizontalAlignment="Center" Style="{StaticResource TitleTextBlockStyle}" Text="{Binding Title}"/>
        <GridView HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
            <GridView.ItemsPanel>
                <ItemsPanelTemplate>
                    <local:CircleItemsPanel Radius="100" Height="600" VerticalAlignment="Stretch"/>
                </ItemsPanelTemplate>
            </GridView.ItemsPanel>
            <GridView.Items>
                <Image Width="50" Source="iTunesArtwork.png"/>
                <Image Width="50" Source="iTunesArtwork.png"/>
                <Image Width="50" Source="iTunesArtwork.png"/>
                <Image Width="50" Source="iTunesArtwork.png"/>
                <Image Width="50" Source="iTunesArtwork.png"/>
                <Image Width="50" Source="iTunesArtwork.png"/>
                <Image Width="50" Source="iTunesArtwork.png"/>
                <Image Width="50" Source="iTunesArtwork.png"/>
                <Image Width="50" Source="iTunesArtwork.png"/>
            </GridView.Items>
        </GridView>
    </Grid>
</Page>

总结了一下,发现原来Xaml下的自定义控件可以这么简单,这么自由,实在给我后续的开发打开了一扇新的大门,以前的自定义都只是限于定制Style,Template,相信以后回有更多好玩app会诞生,最后贴张图。

时间: 2024-08-03 07:47:09

Windows Phone开发手记-WinRT下自定义圆形ItemsControl的相关文章

Windows Phone开发学习笔记(1)---------自定义弹框

Windows Phone开发学习笔记(1) ---------自定义弹框 在WP中自定义弹框是可以通过Popup类实现的. Popup的语法为: [ContentPropertyAttribute("Child")] [LocalizabilityAttribute(LocalizationCategory.None)] public class Popup : FrameworkElement, IAddChild; 这是Popup使用的小列子 Popup codePopup =

Windows Phone开发手记-WinRT下分组拼音的实现

Windows Phone版本号自升入8.1以来,开发者就多了一个选项,开发基于WinRT架构的WP或者Universal Windows App.然而开发框架转为WinRT后,很多原有的WP8基于Sliverlight框架的控件和方法变得不再有效,这无疑带来较大的困扰.今天我要讲述的就是此类问题中较易出现的列表拼音分组方案,本文基于WinRT架构予以实现,下面附上实现效果图: 解决方案: 在WP8下,Silverlight提供了LongListSelector控件,可以方便的实现以上的拼音分组

Windows Phone开发手记-WinRT下启动器替代方案

在WP7/8时代,Silverlight框架提供了很多启动器API,我们可以很方便的使用的,来完成一些系统级的操作.但是随着Win RT架构的WP8.1(SL 8.1除外)的到来,原有的SL下的启动器API均不再可用.所幸,Win RT框架下提供的一些基于Uri协议的方案弥补了部分原有的功能缺失.今天我给大家分享,一些Win RT下的一些启动协议. 1.调用系统内置app 使用方式: await Windows.System.Launcher.LaunchUriAsync(new Uri("ms

Android开发手记(10) 下拉菜单Spinner

1.自定义Spinner 首先,定义Spinner要显示的项目列表/res/values/arrays.xml 1 <?xml version="1.0" encoding="utf-8"?> 2 <resources> 3 <string-array name="citys"> 4 <item>南京</item> 5 <item>徐州</item> 6 <

Android开发之自定义圆形的ImageView的实现

android中的ImageView只能显示矩形的图片,这样一来不能满足我们其他的需求,比如要显示圆形的图片,这个时候,我们就需要自定义ImageView了,其原理就是首先获取到图片的Bitmap,然后进行裁剪圆形的bitmap,然后在onDraw()进行绘制圆形图片输出. 效果图如下: 自定义的圆形的ImageView类的实现代码如下: package com.xc.xcskin.view; import android.content.Context; import android.grap

CentOS7.5下开发systemctl管理的自定义Rsync启动服务程序

CentOS7.5下开发systemctl管理的自定义Rsync启动服务程序 1.1 systemctl知识简介 从CentOS7 Linux开始,系统里的网络服务启动已经从传统的service改成了systemctl(一个systemd工具,主要负责控制systemd系统和服务管理器.),管理开机自启动的命令也从chkconfig改为了systemctl,由systemctl一个命令代替了CentOS7以前系统中的service和chkconfig两个命令. 系统服务的脚本也从传统的路径的/e

iOS项目开发实战——自定义圆形进度提示控件

iOS中默认的进度条是水平方向的进度条,这往往不能满足我们的需求.但是我们可以自定义类似的圆形的进度提示控件,主要使用iOS中的绘图机制来实现.这里我们要实现一个通过按钮点击然后圆形进度提示不断增加的效果. (1)新建一个Cocoa Touch Class,注意要继承自UIView.这个是绘制图形的类,绘制一个圆形的背景和扇形的进度.具体实现如下: import UIKit class ProgressControl: UIView { override init(frame: CGRect)

基于科大讯飞语音云windows平台开发

前记: 前段时间公司没事干,突发奇想想做一个语音识别系统,看起来应该很简单的,但做起来却是各种问题,这个对电气毕业的我,却是挺为难的.谷姐已经离我们而去,感谢度娘,感谢CSDN各位大神,好歹也做的是那么回事了,虽然还是不好用,但基本功能实现了. 该软件使用VS2008C++/CLR开发,由于科大讯飞提供的是C的API接口,结果到这边就是各种不兼容,CLR是基于托管堆运行的,而这个API有是非托管堆的,使用了各种指针,原本打算使用C#来做,最后门外汉的我也没能做到C#和C指针完美结合,真怀恋单片机

Windows驱动开发(中间层)

Windows驱动开发 一.前言 依据<Windows内核安全与驱动开发>及MSDN等网络质料进行学习开发. 二.初步环境 1.下载安装WDK7.1.0(WinDDK\7600.16385.1) 地址:https://msdn.microsoft.com/en-us/windows/hardware/hh852365 2.下载InstDrv软件(用于安装.启动.停止.卸载驱动) 界面如下: 注:srvinstw.exe 也可以安装.卸载sys文件,但需要手动开启.关闭,即在cmd命令窗口下执行