首发 手把手教你制作 Windows8 应用程序内部的 hubtile (动态瓷砖控件) MetroStyle

来源:互联网 发布:知乎和简书哪个更好 编辑:程序博客网 时间:2024/05/01 02:19

在metro 风格中 动态磁贴是他的精髓

 

在wp7 的开发中 我们可以使用hubtile 来制作类似效果

但是在 win8 中并不具备这个功能,

下面我们来通过扩展GridViewItem 来实现  PictureHubTile

<GridViewItem    x:Class="App1.HubTile"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    xmlns:local="using:App1"    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"    mc:Ignorable="d"     x:Name="gridViewItem"    d:DesignHeight="150"    d:DesignWidth="150">    <GridViewItem.Resources>        <Storyboard x:Name="UpperSecStoryboard">            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="SecImg">                <SplineDoubleKeyFrame KeyTime="0:0:1.2" Value="-150" KeySpline="0.29,0.88,0,1"/>            </DoubleAnimationUsingKeyFrames>            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="FirstImg">                <SplineDoubleKeyFrame KeyTime="0:0:1.2" Value="150" KeySpline="1,0,1,0"/>            </DoubleAnimationUsingKeyFrames>        </Storyboard>        <Storyboard x:Name="UpperFirstStoryboard">            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="SecImg">                <SplineDoubleKeyFrame KeyTime="0:0:1.2" Value="0" KeySpline="1,0,1,0"/>            </DoubleAnimationUsingKeyFrames>            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="FirstImg">                <SplineDoubleKeyFrame KeyTime="0:0:1.2" Value="0" KeySpline="0.29,0.88,0,1"/>            </DoubleAnimationUsingKeyFrames>        </Storyboard>    </GridViewItem.Resources>    <Grid Width="{Binding Width, ElementName=gridViewItem}" Height="{Binding Height, ElementName=gridViewItem}">        <Canvas x:Name="PART_LayoutRoot" >            <StackPanel x:Name="PART_Panel">                <Canvas                     Height="{Binding Height, ElementName=gridViewItem}"                     x:Name="FirstImg">                    <Grid  x:Name="PART_FirstContent">                        <Image x:Name="Img1"                               Width="{Binding Width, ElementName=gridViewItem}"                                Height="{Binding Height, ElementName=gridViewItem}"                               Stretch="UniformToFill" VerticalAlignment="Center">                        </Image>                    </Grid>                    <Canvas.RenderTransform>                        <CompositeTransform/>                    </Canvas.RenderTransform>                </Canvas>                <Canvas                     x:Name="SecImg"                     Height="{Binding Height, ElementName=gridViewItem}">                    <Grid x:Name="SecGrid" Background="Red">                        <Image x:Name="Img2"                               Width="{Binding Width, ElementName=gridViewItem}"                                Height="{Binding Height, ElementName=gridViewItem}"                               Stretch="UniformToFill" VerticalAlignment="Center">                        </Image>                    </Grid>                    <Canvas.RenderTransform>                        <CompositeTransform/>                    </Canvas.RenderTransform>                </Canvas>            </StackPanel>        </Canvas>        <ContentPresenter Content="1111" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" x:Name="PART_Title" Margin="0,0,10,7" />    </Grid></GridViewItem>


 

using System;using System.Collections.Generic;using System.Collections.ObjectModel;using System.Diagnostics;using System.IO;using System.Linq;using Windows.Foundation;using Windows.Foundation.Collections;using Windows.UI.Xaml;using Windows.UI.Xaml.Controls;using Windows.UI.Xaml.Controls.Primitives;using Windows.UI.Xaml.Data;using Windows.UI.Xaml.Input;using Windows.UI.Xaml.Media;using Windows.UI.Xaml.Media.Animation;using Windows.UI.Xaml.Media.Imaging;using Windows.UI.Xaml.Navigation;using WinRTXamlToolkit.AwaitableUI;using WinRTXamlToolkit.Imaging;// “用户控件”项模板在 http://go.microsoft.com/fwlink/?LinkId=234236 上提供namespace App1{    public sealed partial class HubTile : GridViewItem    {        #region propdp        #region ImgList        public List<string> ImgList        {            get { return (List<string>)GetValue(ImgListProperty); }            set { SetValue(ImgListProperty, value); }        }        // Using a DependencyProperty as the backing store for ImgList.  This enables animation, styling, binding, etc...        public static readonly DependencyProperty ImgListProperty =            DependencyProperty.Register(            "ImgList",            typeof(List<string>),            typeof(HubTile),            new PropertyMetadata(null, OnImgListChanged));        private static void OnImgListChanged(           DependencyObject d, DependencyPropertyChangedEventArgs e)        {            var target = (HubTile)d;        }        #endregion        #endregion        public HubTile()        {            this.InitializeComponent();            DispatcherTimer timer = new DispatcherTimer();            int index = 0;            bool isFirst = true;            Storyboard storySec = null;            Storyboard storyFir = null;            this.Loaded += ((sender, e) =>            {                storySec = Resources["UpperSecStoryboard"] as Storyboard;                storyFir = Resources["UpperFirstStoryboard"] as Storyboard;                var animation = storySec.Children[0] as DoubleAnimationUsingKeyFrames;                var keyframe = animation.KeyFrames[0] as SplineDoubleKeyFrame;                ((storySec.Children[1] as DoubleAnimationUsingKeyFrames).KeyFrames[0] as SplineDoubleKeyFrame).Value = this.Height;                keyframe.Value = -this.Height;                if (null != ImgList && ImgList.Count > 0)                {                    var url = ImgList[0];                    BitmapImage _source = new BitmapImage(new Uri(url));                    this.Img1.Source = _source;                    timer.Start();                }            });            Random r = new Random(Convert.ToInt32(DateTime.Now.Millisecond));            var second = r.Next(2000, 6000);            Debug.WriteLine(this.Name + "间隔时间:" + second);            timer.Interval = TimeSpan.FromMilliseconds(second);            timer.Tick += (async (o, b) =>            {                index++;                var count = ImgList.Count;                if (null != ImgList)                {                    var url = ImgList[index % count];                    BitmapImage _source = new BitmapImage(new Uri(url));                    Debug.WriteLine(this.Name + "加载图片..." + url);                    if (isFirst)                    {                        this.Img2.Source = _source;                        isFirst = false;                        await storySec.BeginAsync();                        Canvas.SetZIndex(SecImg, 1);                        Canvas.SetZIndex(FirstImg, 2);                    }                    else                    {                        this.Img1.Source = _source;                        isFirst = true;                        await storyFir.BeginAsync();                        Canvas.SetZIndex(SecImg, 2);                        Canvas.SetZIndex(FirstImg, 1);                    }                }            });        }    }}


 

 

 

该样例代码中 我使用了awaitUI 来实现对动画执行的监控,

程序逻辑并不复杂,通过随机的timer 来切换图片 实现

开始菜单的效果

demo 稍后上传

 

最终效果图:

 

 

资源下载地址:http://download.csdn.net/detail/wangrenzhu2011/4760211 

样例项目

原创粉丝点击