標籤:des style blog http io ar color os 使用
這裡的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類。
下面我們需要重寫以下兩個方法 :
- MeasureOverride :使用MeasureOverride方法來報告你所需空間的數量
- ArrangeOverride : 使用ArrangeOverride方法在你的ItemsPanel中真實的布局Item
//CircleItemsPanel.cs
using 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會誕生,最後貼張圖。
Windows Phone開發手記-WinRT下自訂圓形ItemsControl