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

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

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

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

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

  1. <GridViewItem
  2. x:Class="App1.HubTile"
  3. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  4. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  5. xmlns:local="using:App1"
  6. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  7. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  8. mc:Ignorable="d"
  9. x:Name="gridViewItem"
  10. d:DesignHeight="150"
  11. d:DesignWidth="150">
  12. <GridViewItem.Resources>
  13. <Storyboard x:Name="UpperSecStoryboard">
  14. <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="SecImg">
  15. <SplineDoubleKeyFrame KeyTime="0:0:1.2" Value="-150" KeySpline="0.29,0.88,0,1"/>
  16. </DoubleAnimationUsingKeyFrames>
  17. <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="FirstImg">
  18. <SplineDoubleKeyFrame KeyTime="0:0:1.2" Value="150" KeySpline="1,0,1,0"/>
  19. </DoubleAnimationUsingKeyFrames>
  20. </Storyboard>
  21. <Storyboard x:Name="UpperFirstStoryboard">
  22. <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="SecImg">
  23. <SplineDoubleKeyFrame KeyTime="0:0:1.2" Value="0" KeySpline="1,0,1,0"/>
  24. </DoubleAnimationUsingKeyFrames>
  25. <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="FirstImg">
  26. <SplineDoubleKeyFrame KeyTime="0:0:1.2" Value="0" KeySpline="0.29,0.88,0,1"/>
  27. </DoubleAnimationUsingKeyFrames>
  28. </Storyboard>
  29. </GridViewItem.Resources>
  30. <Grid Width="{Binding Width, ElementName=gridViewItem}" Height="{Binding Height, ElementName=gridViewItem}">
  31. <Canvas x:Name="PART_LayoutRoot" >
  32. <StackPanel x:Name="PART_Panel">
  33. <Canvas
  34. Height="{Binding Height, ElementName=gridViewItem}"
  35. x:Name="FirstImg">
  36. <Grid x:Name="PART_FirstContent">
  37. <Image x:Name="Img1"
  38. Width="{Binding Width, ElementName=gridViewItem}"
  39. Height="{Binding Height, ElementName=gridViewItem}"
  40. Stretch="UniformToFill" VerticalAlignment="Center">
  41. </Image>
  42. </Grid>
  43. <Canvas.RenderTransform>
  44. <CompositeTransform/>
  45. </Canvas.RenderTransform>
  46. </Canvas>
  47. <Canvas
  48. x:Name="SecImg"
  49. Height="{Binding Height, ElementName=gridViewItem}">
  50. <Grid x:Name="SecGrid" Background="Red">
  51. <Image x:Name="Img2"
  52. Width="{Binding Width, ElementName=gridViewItem}"
  53. Height="{Binding Height, ElementName=gridViewItem}"
  54. Stretch="UniformToFill" VerticalAlignment="Center">
  55. </Image>
  56. </Grid>
  57. <Canvas.RenderTransform>
  58. <CompositeTransform/>
  59. </Canvas.RenderTransform>
  60. </Canvas>
  61. </StackPanel>
  62. </Canvas>
  63. <ContentPresenter Content="1111" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" x:Name="PART_Title" Margin="0,0,10,7" />
  64. </Grid>
  65. </GridViewItem>
<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>


  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.Diagnostics;
  5. using System.IO;
  6. using System.Linq;
  7. using Windows.Foundation;
  8. using Windows.Foundation.Collections;
  9. using Windows.UI.Xaml;
  10. using Windows.UI.Xaml.Controls;
  11. using Windows.UI.Xaml.Controls.Primitives;
  12. using Windows.UI.Xaml.Data;
  13. using Windows.UI.Xaml.Input;
  14. using Windows.UI.Xaml.Media;
  15. using Windows.UI.Xaml.Media.Animation;
  16. using Windows.UI.Xaml.Media.Imaging;
  17. using Windows.UI.Xaml.Navigation;
  18. using WinRTXamlToolkit.AwaitableUI;
  19. using WinRTXamlToolkit.Imaging;
  20. // “用户控件”项模板在 http://go.microsoft.com/fwlink/?LinkId=234236 上提供
  21. namespace App1
  22. {
  23. public sealed partial class HubTile : GridViewItem
  24. {
  25. #region propdp
  26. #region ImgList
  27. public List<string> ImgList
  28. {
  29. get { return (List<string>)GetValue(ImgListProperty); }
  30. set { SetValue(ImgListProperty, value); }
  31. }
  32. // Using a DependencyProperty as the backing store for ImgList. This enables animation, styling, binding, etc...
  33. public static readonly DependencyProperty ImgListProperty =
  34. DependencyProperty.Register(
  35. "ImgList",
  36. typeof(List<string>),
  37. typeof(HubTile),
  38. new PropertyMetadata(null, OnImgListChanged));
  39. private static void OnImgListChanged(
  40. DependencyObject d, DependencyPropertyChangedEventArgs e)
  41. {
  42. var target = (HubTile)d;
  43. }
  44. #endregion
  45. #endregion
  46. public HubTile()
  47. {
  48. this.InitializeComponent();
  49. DispatcherTimer timer = new DispatcherTimer();
  50. int index = 0;
  51. bool isFirst = true;
  52. Storyboard storySec = null;
  53. Storyboard storyFir = null;
  54. this.Loaded += ((sender, e) =>
  55. {
  56. storySec = Resources["UpperSecStoryboard"] as Storyboard;
  57. storyFir = Resources["UpperFirstStoryboard"] as Storyboard;
  58. var animation = storySec.Children[0] as DoubleAnimationUsingKeyFrames;
  59. var keyframe = animation.KeyFrames[0] as SplineDoubleKeyFrame;
  60. ((storySec.Children[1] as DoubleAnimationUsingKeyFrames).KeyFrames[0] as SplineDoubleKeyFrame).Value = this.Height;
  61. keyframe.Value = -this.Height;
  62. if (null != ImgList && ImgList.Count > 0)
  63. {
  64. var url = ImgList[0];
  65. BitmapImage _source = new BitmapImage(new Uri(url));
  66. this.Img1.Source = _source;
  67. timer.Start();
  68. }
  69. });
  70. Random r = new Random(Convert.ToInt32(DateTime.Now.Millisecond));
  71. var second = r.Next(2000, 6000);
  72. Debug.WriteLine(this.Name + "间隔时间:" + second);
  73. timer.Interval = TimeSpan.FromMilliseconds(second);
  74. timer.Tick += (async (o, b) =>
  75. {
  76. index++;
  77. var count = ImgList.Count;
  78. if (null != ImgList)
  79. {
  80. var url = ImgList[index % count];
  81. BitmapImage _source = new BitmapImage(new Uri(url));
  82. Debug.WriteLine(this.Name + "加载图片..." + url);
  83. if (isFirst)
  84. {
  85. this.Img2.Source = _source;
  86. isFirst = false;
  87. await storySec.BeginAsync();
  88. Canvas.SetZIndex(SecImg, 1);
  89. Canvas.SetZIndex(FirstImg, 2);
  90. }
  91. else
  92. {
  93. this.Img1.Source = _source;
  94. isFirst = true;
  95. await storyFir.BeginAsync();
  96. Canvas.SetZIndex(SecImg, 2);
  97. Canvas.SetZIndex(FirstImg, 1);
  98. }
  99. }
  100. });
  101. }
  102. }
  103. }
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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值