仿windows8 开始菜单 实现HubTileBase 以及仿鲜果联播实现 PulsingTile(脉冲磁贴)

http://blog.csdn.net/wangrenzhu2011/article/details/8750820 (转)

本文章将以如何实现 开始菜单上的tile 为主。

该控件代码经过测试可直接使用。

tile 在我的思路中分为了 3层。

基于ContentControl实现HeaderedContentControl 用于增加Tile种的内容标题

在HeaderedContentControl 的基础上 实现 3d变换 根据触点方向触发不同动画。

实现HubTileBase

在HubTileBase 下我们可以实现多种磁贴

如liveTile(实时反馈)  MosaicTile(仿wp8 风格) PulsingTile(脉冲)等等。。

以下将以PulsingTile 代码为主 来介绍

[csharp] view plaincopyprint?
 
  1. public class HeaderedContentControl : ContentControl  
  2.     {  
  3.         public static readonly DependencyProperty HeaderProperty =  
  4.             DependencyProperty.Register("Header"typeof(object), typeof(HeaderedContentControl), new PropertyMetadata(null));  
  5.         public static readonly DependencyProperty HeaderStyleProperty =  
  6.             DependencyProperty.Register("HeaderStyle"typeof(Style), typeof(HeaderedContentControl), new PropertyMetadata(null));  
  7.         public static readonly DependencyProperty HeaderTemplateProperty =  
  8.             DependencyProperty.Register("HeaderTemplate"typeof(DataTemplate), typeof(HeaderedContentControl), new PropertyMetadata(null));  
  9.         public static readonly DependencyProperty HeaderTemplateSelectorProperty =  
  10.             DependencyProperty.Register("HeaderTemplateSelector"typeof(DataTemplateSelector), typeof(HeaderedContentControl), new PropertyMetadata(null));  
  11.   
  12.         public HeaderedContentControl()  
  13.         {  
  14.             this.DefaultStyleKey = typeof(HeaderedContentControl);  
  15.         }  
  16.   
  17.         public object Header  
  18.         {  
  19.             get  
  20.             {  
  21.                 return base.GetValue(HeaderProperty);  
  22.             }  
  23.             set  
  24.             {  
  25.                 base.SetValue(HeaderProperty, value);  
  26.             }  
  27.         }  
  28.   
  29.         public Style HeaderStyle  
  30.         {  
  31.             get  
  32.             {  
  33.                 return (Style)base.GetValue(HeaderStyleProperty);  
  34.             }  
  35.             set  
  36.             {  
  37.                 base.SetValue(HeaderStyleProperty, value);  
  38.             }  
  39.         }  
  40.   
  41.         public DataTemplate HeaderTemplate  
  42.         {  
  43.             get  
  44.             {  
  45.                 return (DataTemplate)base.GetValue(HeaderTemplateProperty);  
  46.             }  
  47.             set  
  48.             {  
  49.                 base.SetValue(HeaderTemplateProperty, value);  
  50.             }  
  51.         }  
  52.   
  53.         public DataTemplateSelector HeaderTemplateSelector  
  54.         {  
  55.             get  
  56.             {  
  57.                 return (DataTemplateSelector)base.GetValue(HeaderTemplateSelectorProperty);  
  58.             }  
  59.             set  
  60.             {  
  61.                 base.SetValue(HeaderTemplateSelectorProperty, value);  
  62.             }  
  63.         }  
  64.     }  


 

[csharp] view plaincopyprint?
 
  1. public class HubTileBase : HeaderedContentControl  
  2.     {  
  3.         public static readonly DependencyProperty AccentBrushProperty = DependencyProperty.Register("AccentBrush"typeof(Brush), typeof(HubTileBase), new PropertyMetadata(null));  
  4.         public static readonly DependencyProperty GroupNameProperty = DependencyProperty.Register("GroupName"typeof(string), typeof(HubTileBase), new PropertyMetadata(string.Empty));  
  5.         public static readonly DependencyProperty ImageSourceProperty = DependencyProperty.Register("ImageSource"typeof(Windows.UI.Xaml.Media.ImageSource), typeof(HubTileBase), new PropertyMetadata(null));  
  6.         public static readonly DependencyProperty IsFrozenProperty = DependencyProperty.Register("IsFrozen"typeof(bool), typeof(HubTileBase), new PropertyMetadata((bool)false, OnIsFrozenChanged));  
  7.         public static readonly DependencyProperty OverrideDefaultStatesProperty = DependencyProperty.Register("OverrideDefaultStates"typeof(bool), typeof(HubTileBase), new PropertyMetadata((bool)false));  
  8.         private PointerDirection pointerdirection;  
  9.         private bool pointerover;  
  10.         private bool pointerpressed;  
  11.         public static readonly DependencyProperty RotationDepthProperty = DependencyProperty.Register("RotationDepth"typeof(double), typeof(HubTileBase), new PropertyMetadata((double)20.0));  
  12.         public static readonly DependencyProperty ScaleDepthProperty = DependencyProperty.Register("ScaleDepth"typeof(double), typeof(HubTileBase), new PropertyMetadata((double)0.9));  
  13.         private Storyboard storyboard;  
  14.         public static readonly DependencyProperty TilePressDurationProperty = DependencyProperty.Register("TilePressDuration"typeof(TimeSpan), typeof(HubTileBase), new PropertyMetadata(TimeSpan.FromSeconds((double)0.1)));  
  15.         public static readonly DependencyProperty TitleProperty = DependencyProperty.Register("Title"typeof(object), typeof(HubTileBase), new PropertyMetadata(null));  
  16.         public static readonly DependencyProperty TitleStyleProperty = DependencyProperty.Register("TitleStyle"typeof(Style), typeof(HubTileBase), new PropertyMetadata(null));  
  17.   
  18.         private Timeline BuildAnimation(PointerDirection direction)  
  19.         {  
  20.             DoubleAnimationUsingKeyFrames frames = new DoubleAnimationUsingKeyFrames();  
  21.             Storyboard.SetTarget(frames, this);  
  22.             if (direction != PointerDirection.Center)  
  23.             {  
  24.                 PlaneProjection projection2 = new PlaneProjection();  
  25.                 projection2.CenterOfRotationZ = 0.0;  
  26.                 PlaneProjection projection = projection2;  
  27.                 EasingDoubleKeyFrame frame3 = new EasingDoubleKeyFrame();  
  28.                 frame3.KeyTime = ((KeyTime)TimeSpan.FromSeconds((double)0.0));  
  29.                 frame3.Value = 0.0;  
  30.                 EasingDoubleKeyFrame frame = frame3;  
  31.                 EasingDoubleKeyFrame frame4 = new EasingDoubleKeyFrame();  
  32.                 frame4.KeyTime = ((KeyTime)this.TilePressDuration);  
  33.                 EasingDoubleKeyFrame frame2 = frame4;  
  34.                 frames.KeyFrames.Add(frame);  
  35.                 frames.KeyFrames.Add(frame2);  
  36.                 if ((direction == PointerDirection.Left) || (direction == PointerDirection.Bottom))  
  37.                 {  
  38.                     frame2.Value = this.RotationDepth;  
  39.                 }  
  40.                 else if ((direction == PointerDirection.Top) || (direction == PointerDirection.Right))  
  41.                 {  
  42.                     frame2.Value = -this.RotationDepth;  
  43.                 }  
  44.                 if ((direction == PointerDirection.Top) || (direction == PointerDirection.Bottom))  
  45.                 {  
  46.                     Storyboard.SetTargetProperty(frames, "(UIElement.Projection).(PlaneProjection.RotationX)");  
  47.                 }  
  48.                 else if ((direction == PointerDirection.Left) || (direction == PointerDirection.Right))  
  49.                 {  
  50.                     Storyboard.SetTargetProperty(frames, "(UIElement.Projection).(PlaneProjection.RotationY)");  
  51.                 }  
  52.                 if (direction == PointerDirection.Bottom)  
  53.                 {  
  54.                     projection.CenterOfRotationX = 0.5;  
  55.                     projection.CenterOfRotationY = 0.0;  
  56.                 }  
  57.                 else if (direction == PointerDirection.Top)  
  58.                 {  
  59.                     projection.CenterOfRotationX = (0.5);  
  60.                     projection.CenterOfRotationY = (1.0);  
  61.                 }  
  62.                 else if (direction == PointerDirection.Left)  
  63.                 {  
  64.                     projection.CenterOfRotationX = (1.0);  
  65.                     projection.CenterOfRotationY = (0.5);  
  66.                 }  
  67.                 else if (direction == PointerDirection.Right)  
  68.                 {  
  69.                     projection.CenterOfRotationX = (0.0);  
  70.                     projection.CenterOfRotationY = (0.5);  
  71.                 }  
  72.                 base.Projection = (projection);  
  73.             }  
  74.             return frames;  
  75.         }  
  76.   
  77.         private Timeline BuildScaleXAnimation()  
  78.         {  
  79.             DoubleAnimationUsingKeyFrames frames = new DoubleAnimationUsingKeyFrames();  
  80.             Storyboard.SetTarget(frames, this);  
  81.             Storyboard.SetTargetProperty(frames, "(UIElement.RenderTransform).(CompositeTransform.ScaleX)");  
  82.             EasingDoubleKeyFrame frame3 = new EasingDoubleKeyFrame();  
  83.             frame3.KeyTime = ((KeyTime)TimeSpan.FromSeconds((double)0.0));  
  84.             frame3.Value = (1.0);  
  85.             EasingDoubleKeyFrame frame = frame3;  
  86.             EasingDoubleKeyFrame frame4 = new EasingDoubleKeyFrame();  
  87.             frame4.KeyTime = ((KeyTime)this.TilePressDuration);  
  88.             frame4.Value = (this.ScaleDepth);  
  89.             EasingDoubleKeyFrame frame2 = frame4;  
  90.             frames.KeyFrames.Add(frame);  
  91.             frames.KeyFrames.Add(frame2);  
  92.             CompositeTransform transform = new CompositeTransform();  
  93.             base.RenderTransformOrigin = (new Point(0.5, 0.5));  
  94.             base.RenderTransform = (transform);  
  95.             return frames;  
  96.         }  
  97.   
  98.         private Timeline BuildScaleYAnimation()  
  99.         {  
  100.             DoubleAnimationUsingKeyFrames frames = new DoubleAnimationUsingKeyFrames();  
  101.             Storyboard.SetTarget(frames, this);  
  102.             Storyboard.SetTargetProperty(frames, "(UIElement.RenderTransform).(CompositeTransform.ScaleY)");  
  103.             EasingDoubleKeyFrame frame3 = new EasingDoubleKeyFrame();  
  104.             frame3.KeyTime = ((KeyTime)TimeSpan.FromSeconds((double)0.0));  
  105.             frame3.Value = (1.0);  
  106.             EasingDoubleKeyFrame frame = frame3;  
  107.             EasingDoubleKeyFrame frame4 = new EasingDoubleKeyFrame();  
  108.             frame4.KeyTime = ((KeyTime)this.TilePressDuration);  
  109.             frame4.Value = (this.ScaleDepth);  
  110.             EasingDoubleKeyFrame frame2 = frame4;  
  111.             frames.KeyFrames.Add(frame);  
  112.             frames.KeyFrames.Add(frame2);  
  113.             CompositeTransform transform = new CompositeTransform();  
  114.             base.RenderTransform = (transform);  
  115.             base.RenderTransformOrigin = (new Point(0.5, 0.5));  
  116.             return frames;  
  117.         }  
  118.   
  119.         private void ExecutePointerReleased()  
  120.         {  
  121.             if (this.pointerpressed)  
  122.             {  
  123.                 if (this.OverrideDefaultStates)  
  124.                 {  
  125.                     if (this.pointerover)  
  126.                     {  
  127.                         VisualStateManager.GoToState(this"PointerOver"true);  
  128.                     }  
  129.                     else  
  130.                     {  
  131.                         VisualStateManager.GoToState(this"Normal"true);  
  132.                     }  
  133.                 }  
  134.                 else if (this.storyboard != null)  
  135.                 {  
  136.                     if (this.pointerdirection != PointerDirection.Center)  
  137.                     {  
  138.                         DoubleAnimationUsingKeyFrames frames = this.storyboard.Children[0] as DoubleAnimationUsingKeyFrames;  
  139.                         if (frames != null)  
  140.                         {  
  141.                             EasingDoubleKeyFrame frame = frames.KeyFrames[0] as EasingDoubleKeyFrame;  
  142.                             EasingDoubleKeyFrame frame2 = frames.KeyFrames[1] as EasingDoubleKeyFrame;  
  143.                             frame.Value = (frame2.Value);  
  144.                             frame2.Value = (0.0);  
  145.                         }  
  146.                     }  
  147.                     else  
  148.                     {  
  149.                         DoubleAnimationUsingKeyFrames frames2 = this.storyboard.Children[0] as DoubleAnimationUsingKeyFrames;  
  150.                         DoubleAnimationUsingKeyFrames frames3 = this.storyboard.Children[1] as DoubleAnimationUsingKeyFrames;  
  151.                         if (frames2 != null)  
  152.                         {  
  153.                             EasingDoubleKeyFrame frame3 = frames2.KeyFrames[0] as EasingDoubleKeyFrame;  
  154.                             EasingDoubleKeyFrame frame4 = frames2.KeyFrames[1] as EasingDoubleKeyFrame;  
  155.                             frame3.Value = (frame4.Value);  
  156.                             frame4.Value = (1.0);  
  157.                         }  
  158.                         if (frames3 != null)  
  159.                         {  
  160.                             EasingDoubleKeyFrame frame5 = frames3.KeyFrames[0] as EasingDoubleKeyFrame;  
  161.                             EasingDoubleKeyFrame frame6 = frames3.KeyFrames[1] as EasingDoubleKeyFrame;  
  162.                             frame5.Value = (frame6.Value);  
  163.                             frame6.Value = (1.0);  
  164.                         }  
  165.                     }  
  166.                     this.storyboard.Begin();  
  167.                 }  
  168.             }  
  169.             this.pointerpressed = false;  
  170.         }  
  171.   
  172.         protected virtual void OnIsFrozenChanged(DependencyPropertyChangedEventArgs e)  
  173.         {  
  174.         }  
  175.   
  176.         private static void OnIsFrozenChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)  
  177.         {  
  178.             HubTileBase base2 = sender as HubTileBase;  
  179.             if (base2 != null)  
  180.             {  
  181.                 base2.OnIsFrozenChanged(e);  
  182.             }  
  183.         }  
  184.   
  185.         protected override void OnPointerEntered(PointerRoutedEventArgs e)  
  186.         {  
  187.             this.pointerover = true;  
  188.             VisualStateManager.GoToState(this"PointerOver"true);  
  189.             base.OnPointerEntered(e);  
  190.         }  
  191.   
  192.         protected override void OnPointerExited(PointerRoutedEventArgs e)  
  193.         {  
  194.             if (this.pointerpressed)  
  195.             {  
  196.                 this.ExecutePointerReleased();  
  197.             }  
  198.             this.pointerover = false;  
  199.             VisualStateManager.GoToState(this"Normal"true);  
  200.             base.OnPointerExited(e);  
  201.         }  
  202.   
  203.         protected override void OnPointerPressed(PointerRoutedEventArgs e)  
  204.         {  
  205.             this.pointerpressed = true;  
  206.             if (this.OverrideDefaultStates)  
  207.             {  
  208.                 VisualStateManager.GoToState(this"PointerPressed"true);  
  209.             }  
  210.             else  
  211.             {  
  212.                 PointerPoint currentpoint = e.GetCurrentPoint(this);  
  213.                 var point = currentpoint.Position;  
  214.                 double num = base.ActualWidth / 3.0;  
  215.                 double num2 = base.ActualHeight / 3.0;  
  216.                 Dictionary<PointerDirection, Rect> pieces = new Dictionary<PointerDirection, Rect>();  
  217.                 pieces.Add(PointerDirection.TopLeft, new Rect(0.0, 0.0, num, num2));  
  218.                 pieces.Add(PointerDirection.Top, new Rect(num, 0.0, num, num2));  
  219.                 pieces.Add(PointerDirection.TopRight, new Rect(num * 2.0, 0.0, num, num2));  
  220.                 pieces.Add(PointerDirection.Left, new Rect(0.0, num2, num, num2));  
  221.                 pieces.Add(PointerDirection.Center, new Rect(num, num2, num, num2));  
  222.                 pieces.Add(PointerDirection.Right, new Rect(num * 2.0, num2, num, num2));  
  223.                 pieces.Add(PointerDirection.BottomLeft, new Rect(0.0, num2 * 2.0, num, num2));  
  224.                 pieces.Add(PointerDirection.Bottom, new Rect(num, num2 * 2.0, num, num2));  
  225.                 pieces.Add(PointerDirection.BottomRight, new Rect(num * 2.0, num2 * 2.0, num, num2));  
  226.                 this.pointerdirection =  
  227.                   (from _direction in pieces.Keys  
  228.                    where pieces[_direction].Contains(point)  
  229.                    select _direction).FirstOrDefault();  
  230.                 this.storyboard = new Storyboard();  
  231.                 if (this.pointerdirection <= PointerDirection.Center)  
  232.                 {  
  233.                     if (this.pointerdirection == PointerDirection.Center)  
  234.                     {  
  235.                         Timeline timeline = this.BuildScaleXAnimation();  
  236.                         Timeline timeline2 = this.BuildScaleYAnimation();  
  237.                         this.storyboard.Children.Add(timeline);  
  238.                         this.storyboard.Children.Add(timeline2);  
  239.                         this.storyboard.Begin();  
  240.                     }  
  241.                     else  
  242.                     {  
  243.                         Timeline timeline3 = this.BuildAnimation(this.pointerdirection);  
  244.                         this.storyboard.Children.Add(timeline3);  
  245.                         this.storyboard.Begin();  
  246.                     }  
  247.                 }  
  248.                 else if (this.pointerdirection == PointerDirection.TopLeft)  
  249.                 {  
  250.                     if (currentpoint.Position.X > currentpoint.Position.Y)  
  251.                     {  
  252.                         Timeline timeline4 = this.BuildAnimation(PointerDirection.Top);  
  253.                         this.storyboard.Children.Add(timeline4);  
  254.                         this.storyboard.Begin();  
  255.                     }  
  256.                     else  
  257.                     {  
  258.                         Timeline timeline5 = this.BuildAnimation(PointerDirection.Left);  
  259.                         this.storyboard.Children.Add(timeline5);  
  260.                         this.storyboard.Begin();  
  261.                     }  
  262.                 }  
  263.                 else if (this.pointerdirection == PointerDirection.TopRight)  
  264.                 {  
  265.                     if (currentpoint.Position.Y > (num2 - (currentpoint.Position.X - (num * 2.0))))  
  266.                     {  
  267.                         Timeline timeline6 = this.BuildAnimation(PointerDirection.Right);  
  268.                         this.storyboard.Children.Add(timeline6);  
  269.                         this.storyboard.Begin();  
  270.                     }  
  271.                     else  
  272.                     {  
  273.                         Timeline timeline7 = this.BuildAnimation(PointerDirection.Top);  
  274.                         this.storyboard.Children.Add(timeline7);  
  275.                         this.storyboard.Begin();  
  276.                     }  
  277.                 }  
  278.                 else if (this.pointerdirection == PointerDirection.BottomLeft)  
  279.                 {  
  280.                     if ((currentpoint.Position.Y - (num2 * 2.0)) > (num2 - currentpoint.Position.X))  
  281.                     {  
  282.                         Timeline timeline8 = this.BuildAnimation(PointerDirection.Bottom);  
  283.                         this.storyboard.Children.Add(timeline8);  
  284.                         this.storyboard.Begin();  
  285.                     }  
  286.                     else  
  287.                     {  
  288.                         Timeline timeline9 = this.BuildAnimation(PointerDirection.Left);  
  289.                         this.storyboard.Children.Add(timeline9);  
  290.                         this.storyboard.Begin();  
  291.                     }  
  292.                 }  
  293.                 else if (currentpoint.Position.X > currentpoint.Position.Y)  
  294.                 {  
  295.                     Timeline timeline10 = this.BuildAnimation(PointerDirection.Right);  
  296.                     this.storyboard.Children.Add(timeline10);  
  297.                     this.storyboard.Begin();  
  298.                 }  
  299.                 else  
  300.                 {  
  301.                     Timeline timeline11 = this.BuildAnimation(PointerDirection.Bottom);  
  302.                     this.storyboard.Children.Add(timeline11);  
  303.                     this.storyboard.Begin();  
  304.                 }  
  305.             }  
  306.             base.OnPointerPressed(e);  
  307.         }  
  308.   
  309.         protected override void OnPointerReleased(PointerRoutedEventArgs e)  
  310.         {  
  311.             this.ExecutePointerReleased();  
  312.             base.OnPointerReleased(e);  
  313.         }  
  314.   
  315.         public Brush AccentBrush  
  316.         {  
  317.             get  
  318.             {  
  319.                 return (Brush)base.GetValue(AccentBrushProperty);  
  320.             }  
  321.             set  
  322.             {  
  323.                 base.SetValue(AccentBrushProperty, value);  
  324.             }  
  325.         }  
  326.   
  327.         public string GroupName  
  328.         {  
  329.             get  
  330.             {  
  331.                 return (string)((string)base.GetValue(GroupNameProperty));  
  332.             }  
  333.             set  
  334.             {  
  335.                 base.SetValue(GroupNameProperty, value);  
  336.             }  
  337.         }  
  338.   
  339.         public Windows.UI.Xaml.Media.ImageSource ImageSource  
  340.         {  
  341.             get  
  342.             {  
  343.                 return (Windows.UI.Xaml.Media.ImageSource)base.GetValue(ImageSourceProperty);  
  344.             }  
  345.             set  
  346.             {  
  347.                 base.SetValue(ImageSourceProperty, value);  
  348.             }  
  349.         }  
  350.   
  351.         public bool IsFrozen  
  352.         {  
  353.             get  
  354.             {  
  355.                 return (bool)((bool)base.GetValue(IsFrozenProperty));  
  356.             }  
  357.             set  
  358.             {  
  359.                 base.SetValue(IsFrozenProperty, (bool)value);  
  360.             }  
  361.         }  
  362.   
  363.         public bool OverrideDefaultStates  
  364.         {  
  365.             get  
  366.             {  
  367.                 return (bool)((bool)base.GetValue(OverrideDefaultStatesProperty));  
  368.             }  
  369.             set  
  370.             {  
  371.                 base.SetValue(OverrideDefaultStatesProperty, (bool)value);  
  372.             }  
  373.         }  
  374.   
  375.         public double RotationDepth  
  376.         {  
  377.             get  
  378.             {  
  379.                 return (double)((double)base.GetValue(RotationDepthProperty));  
  380.             }  
  381.             set  
  382.             {  
  383.                 base.SetValue(RotationDepthProperty, (double)value);  
  384.             }  
  385.         }  
  386.   
  387.         public double ScaleDepth  
  388.         {  
  389.             get  
  390.             {  
  391.                 return (double)((double)base.GetValue(ScaleDepthProperty));  
  392.             }  
  393.             set  
  394.             {  
  395.                 base.SetValue(ScaleDepthProperty, (double)value);  
  396.             }  
  397.         }  
  398.   
  399.         public TimeSpan TilePressDuration  
  400.         {  
  401.             get  
  402.             {  
  403.                 return (TimeSpan)base.GetValue(TilePressDurationProperty);  
  404.             }  
  405.             set  
  406.             {  
  407.                 base.SetValue(TilePressDurationProperty, value);  
  408.             }  
  409.         }  
  410.   
  411.         public object Title  
  412.         {  
  413.             get  
  414.             {  
  415.                 return base.GetValue(TitleProperty);  
  416.             }  
  417.             set  
  418.             {  
  419.                 base.SetValue(TitleProperty, value);  
  420.             }  
  421.         }  
  422.   
  423.         public Style TitleStyle  
  424.         {  
  425.             get  
  426.             {  
  427.                 return (Style)base.GetValue(TitleStyleProperty);  
  428.             }  
  429.             set  
  430.             {  
  431.                 base.SetValue(TitleStyleProperty, value);  
  432.             }  
  433.         }  
  434.     }  


 

[csharp] view plaincopyprint?
 
  1. public static class HubTileService  
  2.     {  
  3.         private static List<WeakReference> Tiles = new List<WeakReference>();  
  4.   
  5.         internal static void Dequeue(HubTileBase tile)  
  6.         {  
  7.             foreach (WeakReference reference in Tiles)  
  8.             {  
  9.                 if (reference.Target == tile)  
  10.                 {  
  11.                     Tiles.Remove(reference);  
  12.                     break;  
  13.                 }  
  14.             }  
  15.         }  
  16.   
  17.         internal static void Enqueue(HubTileBase tile)  
  18.         {  
  19.             WeakReference reference = new WeakReference(tile, false);  
  20.             Tiles.Add(reference);  
  21.         }  
  22.   
  23.         public static void Freeze(HubTileBase tile)  
  24.         {  
  25.             foreach (WeakReference reference in Tiles)  
  26.             {  
  27.                 if (reference.Target == tile)  
  28.                 {  
  29.                     HubTileBase base2 = reference.Target as HubTileBase;  
  30.                     base2.IsFrozen = true;  
  31.                     break;  
  32.                 }  
  33.             }  
  34.         }  
  35.   
  36.         public static void Freeze(string groupname)  
  37.         {  
  38.             using (List<WeakReference>.Enumerator enumerator = Tiles.GetEnumerator())  
  39.             {  
  40.                 while (enumerator.MoveNext())  
  41.                 {  
  42.                     HubTileBase base2 = enumerator.Current.Target as HubTileBase;  
  43.                     if ((base2 != null) && (base2.GroupName == groupname))  
  44.                     {  
  45.                         base2.IsFrozen = false;  
  46.                     }  
  47.                 }  
  48.             }  
  49.         }  
  50.   
  51.         public static void UnFreeze(HubTileBase tile)  
  52.         {  
  53.             foreach (WeakReference reference in Tiles)  
  54.             {  
  55.                 if (reference.Target == tile)  
  56.                 {  
  57.                     HubTileBase base2 = reference.Target as HubTileBase;  
  58.                     base2.IsFrozen = false;  
  59.                     break;  
  60.                 }  
  61.             }  
  62.         }  
  63.   
  64.         public static void UnFreeze(string groupname)  
  65.         {  
  66.             using (List<WeakReference>.Enumerator enumerator = Tiles.GetEnumerator())  
  67.             {  
  68.                 while (enumerator.MoveNext())  
  69.                 {  
  70.                     HubTileBase base2 = enumerator.Current.Target as HubTileBase;  
  71.                     if ((base2 != null) && (base2.GroupName == groupname))  
  72.                     {  
  73.                         base2.IsFrozen = false;  
  74.                     }  
  75.                 }  
  76.             }  
  77.         }  
  78.     }  


 

[csharp] view plaincopyprint?
 
  1. public enum PointerDirection  
  2.  {  
  3.      Left,  
  4.      Top,  
  5.      Right,  
  6.      Bottom,  
  7.      Center,  
  8.      TopLeft,  
  9.      TopRight,  
  10.      BottomLeft,  
  11.      BottomRight  
  12.  }  


 

[csharp] view plaincopyprint?
 
  1. public class PulsingTile : HubTileBase  
  2.     {  
  3.         protected ContentPresenter PART_Content;  
  4.         public static readonly DependencyProperty PulseDurationProperty = DependencyProperty.Register("PulseDuration"typeof(TimeSpan), typeof(PulsingTile), new PropertyMetadata(TimeSpan.FromSeconds((double)4.0), new PropertyChangedCallback(OnValueChanged)));  
  5.         public static readonly DependencyProperty PulseScaleProperty = DependencyProperty.Register("PulseScale"typeof(double), typeof(PulsingTile), new PropertyMetadata((double)1.0, new PropertyChangedCallback(OnValueChanged)));  
  6.         private Storyboard pulseStroyboard;  
  7.         public static readonly DependencyProperty RadiusXProperty = DependencyProperty.Register("RadiusX"typeof(double), typeof(PulsingTile), new PropertyMetadata((double)0.0, new PropertyChangedCallback(OnValueChanged)));  
  8.         public static readonly DependencyProperty RadiusYProperty = DependencyProperty.Register("RadiusY"typeof(double), typeof(PulsingTile), new PropertyMetadata((double)0.0, new PropertyChangedCallback(OnValueChanged)));  
  9.         private Storyboard roatationStroyboard;  
  10.         public static readonly DependencyProperty TranslateDurationProperty = DependencyProperty.Register("TranslateDuration"typeof(TimeSpan), typeof(PulsingTile), new PropertyMetadata(TimeSpan.FromSeconds((double)4.0), new PropertyChangedCallback(OnValueChanged)));  
  11.   
  12.         public PulsingTile()  
  13.         {  
  14.             base.DefaultStyleKey = (typeof(PulsingTile));  
  15.             PulsingTile tile = this;  
  16.             this.Loaded += this.OnLoaded;  
  17.         }  
  18.   
  19.         private void AnimateContent()  
  20.         {  
  21.             if (this.PART_Content != null)  
  22.             {  
  23.                 RectangleGeometry geometry = new RectangleGeometry();  
  24.                 geometry.Rect = (new Rect(0.0, 0.0, base.ActualWidth, base.ActualHeight));  
  25.                 base.Clip = (geometry);  
  26.                 this.PART_Content.RenderTransform = (new CompositeTransform());  
  27.                 this.PART_Content.RenderTransformOrigin = (new Point(0.5, 0.5));  
  28.                 this.PART_Content.Visibility = Windows.UI.Xaml.Visibility.Visible;  
  29.                 DoubleAnimationUsingKeyFrames frames = this.BuildXTimeLine(this.RadiusX, this.RadiusY);  
  30.                 DoubleAnimationUsingKeyFrames frames2 = this.BuildYTimeLine(this.RadiusX, this.RadiusY);  
  31.                 this.roatationStroyboard = new Storyboard();  
  32.                 RepeatBehavior behavior = new RepeatBehavior();  
  33.                 behavior.Type = (RepeatBehaviorType.Forever);  
  34.                 this.roatationStroyboard.RepeatBehavior = (behavior);  
  35.                 this.roatationStroyboard.Children.Add(frames);  
  36.                 this.roatationStroyboard.Children.Add(frames2);  
  37.                 Storyboard.SetTarget(frames, this.PART_Content);  
  38.                 Storyboard.SetTarget(frames2, this.PART_Content);  
  39.                 Storyboard.SetTargetProperty(frames, "(UIElement.RenderTransform).(CompositeTransform.TranslateX)");  
  40.                 Storyboard.SetTargetProperty(frames2, "(UIElement.RenderTransform).(CompositeTransform.TranslateY)");  
  41.                 DoubleAnimationUsingKeyFrames frames3 = this.BuildPulseXTimeLine(this.PulseScale);  
  42.                 DoubleAnimationUsingKeyFrames frames4 = this.BuildPulseYTimeLine(this.PulseScale);  
  43.                 this.pulseStroyboard = new Storyboard();  
  44.                 this.pulseStroyboard.AutoReverse = (true);  
  45.                 this.pulseStroyboard.SpeedRatio = (0.4);  
  46.                 RepeatBehavior behavior2 = new RepeatBehavior();  
  47.                 behavior2.Type = (RepeatBehaviorType.Forever);  
  48.                 this.pulseStroyboard.RepeatBehavior = (behavior2);  
  49.                 this.pulseStroyboard.Children.Add(frames3);  
  50.                 this.pulseStroyboard.Children.Add(frames4);  
  51.                 Storyboard.SetTarget(frames3, this.PART_Content);  
  52.                 Storyboard.SetTarget(frames4, this.PART_Content);  
  53.                 Storyboard.SetTargetProperty(frames3, "(UIElement.RenderTransform).(CompositeTransform.ScaleX)");  
  54.                 Storyboard.SetTargetProperty(frames4, "(UIElement.RenderTransform).(CompositeTransform.ScaleY)");  
  55.                 this.pulseStroyboard.Begin();  
  56.                 this.roatationStroyboard.Begin();  
  57.             }  
  58.         }  
  59.   
  60.         private DoubleAnimationUsingKeyFrames BuildPulseXTimeLine(double pulseScale)  
  61.         {  
  62.             TimeSpan pulseDuration = this.PulseDuration;  
  63.             SplineDoubleKeyFrame frame = new SplineDoubleKeyFrame();  
  64.             frame.Value = (1.0);  
  65.             frame.KeyTime = ((KeyTime)TimeSpan.FromSeconds((double)0.0));  
  66.             EasingDoubleKeyFrame frame2 = new EasingDoubleKeyFrame();  
  67.             frame2.Value = (pulseScale);  
  68.             frame2.KeyTime = (KeyTime.FromTimeSpan(this.PulseDuration));  
  69.             SineEase ease = new SineEase();  
  70.             ease.EasingMode = EasingMode.EaseOut;  
  71.             frame2.EasingFunction = (ease);  
  72.             DoubleAnimationUsingKeyFrames frames = new DoubleAnimationUsingKeyFrames();  
  73.             frames.KeyFrames.Add(frame);  
  74.             frames.KeyFrames.Add(frame2);  
  75.             return frames;  
  76.         }  
  77.   
  78.         private DoubleAnimationUsingKeyFrames BuildPulseYTimeLine(double pulseScale)  
  79.         {  
  80.             TimeSpan pulseDuration = this.PulseDuration;  
  81.             SplineDoubleKeyFrame frame = new SplineDoubleKeyFrame();  
  82.             frame.Value = (1.0);  
  83.             frame.KeyTime = ((KeyTime)TimeSpan.FromSeconds((double)0.0));  
  84.             EasingDoubleKeyFrame frame2 = new EasingDoubleKeyFrame();  
  85.             frame2.Value = (pulseScale);  
  86.             frame2.KeyTime = (KeyTime.FromTimeSpan(this.PulseDuration));  
  87.             SineEase ease = new SineEase();  
  88.             ease.EasingMode = EasingMode.EaseOut;  
  89.             frame2.EasingFunction = (ease);  
  90.             DoubleAnimationUsingKeyFrames frames = new DoubleAnimationUsingKeyFrames();  
  91.             frames.KeyFrames.Add(frame);  
  92.             frames.KeyFrames.Add(frame2);  
  93.             return frames;  
  94.         }  
  95.   
  96.         private DoubleAnimationUsingKeyFrames BuildXTimeLine(double radiusx, double radiusy)  
  97.         {  
  98.             TimeSpan translateDuration = this.TranslateDuration;  
  99.             DiscreteDoubleKeyFrame frame = new DiscreteDoubleKeyFrame();  
  100.             frame.Value = (0.0);  
  101.             frame.KeyTime = ((KeyTime)TimeSpan.FromSeconds((double)0.0));  
  102.             EasingDoubleKeyFrame frame2 = new EasingDoubleKeyFrame();  
  103.             frame2.Value = (radiusx);  
  104.             frame2.KeyTime = (KeyTime.FromTimeSpan(TimeSpan.FromSeconds((double)(translateDuration.TotalSeconds / 4.0))));  
  105.             SineEase ease = new SineEase();  
  106.             ease.EasingMode = EasingMode.EaseIn;  
  107.             frame2.EasingFunction = (ease);  
  108.             EasingDoubleKeyFrame frame3 = new EasingDoubleKeyFrame();  
  109.             frame3.Value = (0.0);  
  110.             frame3.KeyTime = (KeyTime.FromTimeSpan(TimeSpan.FromSeconds((double)(translateDuration.TotalSeconds / 2.0))));  
  111.             SineEase ease2 = new SineEase();  
  112.             ease2.EasingMode = EasingMode.EaseInOut;  
  113.             frame3.EasingFunction = ease2;  
  114.             EasingDoubleKeyFrame frame4 = new EasingDoubleKeyFrame();  
  115.             frame4.Value = (-radiusx);  
  116.             frame4.KeyTime = (KeyTime.FromTimeSpan(TimeSpan.FromSeconds((double)((translateDuration.TotalSeconds * 3.0) / 4.0))));  
  117.             SineEase ease3 = new SineEase();  
  118.             ease3.EasingMode = EasingMode.EaseIn;  
  119.             frame4.EasingFunction = (ease3);  
  120.             EasingDoubleKeyFrame frame5 = new EasingDoubleKeyFrame();  
  121.             frame5.Value = (0.0);  
  122.             frame5.KeyTime = (KeyTime.FromTimeSpan(translateDuration));  
  123.             SineEase ease4 = new SineEase();  
  124.             ease4.EasingMode = EasingMode.EaseInOut;  
  125.             frame5.EasingFunction = (ease4);  
  126.             DoubleAnimationUsingKeyFrames frames = new DoubleAnimationUsingKeyFrames();  
  127.             frames.KeyFrames.Add(frame);  
  128.             frames.KeyFrames.Add(frame2);  
  129.             frames.KeyFrames.Add(frame3);  
  130.             frames.KeyFrames.Add(frame4);  
  131.             frames.KeyFrames.Add(frame5);  
  132.             return frames;  
  133.         }  
  134.   
  135.         private DoubleAnimationUsingKeyFrames BuildYTimeLine(double radiusx, double radiusy)  
  136.         {  
  137.             TimeSpan translateDuration = this.TranslateDuration;  
  138.             DiscreteDoubleKeyFrame frame = new DiscreteDoubleKeyFrame();  
  139.             frame.Value = (0.0);  
  140.             frame.KeyTime = ((KeyTime)TimeSpan.FromSeconds((double)0.0));  
  141.             EasingDoubleKeyFrame frame2 = new EasingDoubleKeyFrame();  
  142.             frame2.Value = (this.RadiusY);  
  143.             frame2.KeyTime = (KeyTime.FromTimeSpan(TimeSpan.FromSeconds((double)(translateDuration.TotalSeconds / 4.0))));  
  144.             SineEase ease = new SineEase();  
  145.             ease.EasingMode = EasingMode.EaseIn;  
  146.             frame2.EasingFunction = (ease);  
  147.             EasingDoubleKeyFrame frame3 = new EasingDoubleKeyFrame();  
  148.             frame3.Value = (2.0 * this.RadiusY);  
  149.             frame3.KeyTime = (KeyTime.FromTimeSpan(TimeSpan.FromSeconds((double)(translateDuration.TotalSeconds / 2.0))));  
  150.             SineEase ease2 = new SineEase();  
  151.             ease2.EasingMode = EasingMode.EaseIn;  
  152.             frame3.EasingFunction = (ease2);  
  153.             EasingDoubleKeyFrame frame4 = new EasingDoubleKeyFrame();  
  154.             frame4.Value = (radiusy);  
  155.             frame4.KeyTime = (KeyTime.FromTimeSpan(TimeSpan.FromSeconds((double)((translateDuration.TotalSeconds * 3.0) / 4.0))));  
  156.             SineEase ease3 = new SineEase();  
  157.             ease3.EasingMode = EasingMode.EaseInOut;  
  158.             frame4.EasingFunction = (ease3);  
  159.             EasingDoubleKeyFrame frame5 = new EasingDoubleKeyFrame();  
  160.             frame5.Value = (0.0);  
  161.             frame5.KeyTime = (KeyTime.FromTimeSpan(translateDuration));  
  162.             SineEase ease4 = new SineEase();  
  163.             ease4.EasingMode = EasingMode.EaseIn;  
  164.             frame5.EasingFunction = (ease4);  
  165.             DoubleAnimationUsingKeyFrames frames = new DoubleAnimationUsingKeyFrames();  
  166.             frames.KeyFrames.Add(frame);  
  167.             frames.KeyFrames.Add(frame2);  
  168.             frames.KeyFrames.Add(frame3);  
  169.             frames.KeyFrames.Add(frame4);  
  170.             frames.KeyFrames.Add(frame5);  
  171.             return frames;  
  172.         }  
  173.   
  174.         protected override void OnApplyTemplate()  
  175.         {  
  176.             base.OnApplyTemplate();  
  177.             this.PART_Content = base.GetTemplateChild("PART_Content"as ContentPresenter;  
  178.         }  
  179.   
  180.         protected override void OnIsFrozenChanged(DependencyPropertyChangedEventArgs e)  
  181.         {  
  182.             if (base.IsFrozen)  
  183.             {  
  184.                 if (this.pulseStroyboard != null)  
  185.                 {  
  186.                     this.pulseStroyboard.Stop();  
  187.                 }  
  188.                 if (this.roatationStroyboard != null)  
  189.                 {  
  190.                     this.roatationStroyboard.Stop();  
  191.                 }  
  192.             }  
  193.             else  
  194.             {  
  195.                 if (this.pulseStroyboard != null)  
  196.                 {  
  197.                     this.pulseStroyboard.Begin();  
  198.                 }  
  199.                 if (this.roatationStroyboard != null)  
  200.                 {  
  201.                     this.roatationStroyboard.Begin();  
  202.                 }  
  203.             }  
  204.         }  
  205.   
  206.         private void OnLoaded(object sender, RoutedEventArgs e)  
  207.         {  
  208.             HubTileService.Enqueue(this);  
  209.             PulsingTile tile = this;  
  210.             this.Loaded += PulsingTile_Unloaded;  
  211.             this.StartAnimation();  
  212.         }  
  213.   
  214.         private static void OnValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)  
  215.         {  
  216.             PulsingTile tile = sender as PulsingTile;  
  217.             if (tile != null)  
  218.             {  
  219.                 tile.StopAnimation();  
  220.                 tile.StartAnimation();  
  221.             }  
  222.         }  
  223.   
  224.         private void PulsingTile_Unloaded(object sender, RoutedEventArgs e)  
  225.         {  
  226.             HubTileService.Dequeue(this);  
  227.             this.Unloaded -= PulsingTile_Unloaded;  
  228.         }  
  229.   
  230.         private void StartAnimation()  
  231.         {  
  232.             this.AnimateContent();  
  233.         }  
  234.   
  235.         private void StopAnimation()  
  236.         {  
  237.             if (this.pulseStroyboard != null)  
  238.             {  
  239.                 this.pulseStroyboard.Stop();  
  240.             }  
  241.             if (this.roatationStroyboard != null)  
  242.             {  
  243.                 this.roatationStroyboard.Stop();  
  244.             }  
  245.         }  
  246.   
  247.         public TimeSpan PulseDuration  
  248.         {  
  249.             get  
  250.             {  
  251.                 return (TimeSpan)base.GetValue(PulseDurationProperty);  
  252.             }  
  253.             set  
  254.             {  
  255.                 base.SetValue(PulseDurationProperty, value);  
  256.             }  
  257.         }  
  258.   
  259.         public double PulseScale  
  260.         {  
  261.             get  
  262.             {  
  263.                 return (double)((double)base.GetValue(PulseScaleProperty));  
  264.             }  
  265.             set  
  266.             {  
  267.                 base.SetValue(PulseScaleProperty, (double)value);  
  268.             }  
  269.         }  
  270.   
  271.         public double RadiusX  
  272.         {  
  273.             get  
  274.             {  
  275.                 return (double)((double)base.GetValue(RadiusXProperty));  
  276.             }  
  277.             set  
  278.             {  
  279.                 base.SetValue(RadiusXProperty, (double)value);  
  280.             }  
  281.         }  
  282.   
  283.         public double RadiusY  
  284.         {  
  285.             get  
  286.             {  
  287.                 return (double)((double)base.GetValue(RadiusYProperty));  
  288.             }  
  289.             set  
  290.             {  
  291.                 base.SetValue(RadiusYProperty, (double)value);  
  292.             }  
  293.         }  
  294.   
  295.         public TimeSpan TranslateDuration  
  296.         {  
  297.             get  
  298.             {  
  299.                 return (TimeSpan)base.GetValue(TranslateDurationProperty);  
  300.             }  
  301.             set  
  302.             {  
  303.                 base.SetValue(TranslateDurationProperty, value);  
  304.             }  
  305.         }  
  306.     }  


 

  1. <ResourceDictionary  
  2.     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"   
  3.     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
  4.     xmlns:PulsingTile="using:WinRTXamlToolkit.Controls">  
  5.      
  6.     <SolidColorBrush x:Key="AccentBrush" Color="#FF1FAEFF" />  
  7.   
  8.   
  9.   
  10.     <DataTemplate x:Key="ImageTileContentTemplate">  
  11.         <Grid>  
  12.             <Rectangle Fill="{Binding Background}"/>  
  13.             <Rectangle Fill="White" Opacity="{Binding Opacity}"/>  
  14.             <Image Source="{Binding Image}" Width="{Binding ImageWidth}" Height="{Binding ImageHeight}"  
  15.                    HorizontalAlignment="{Binding HorizontalImageAlignment}"  
  16.                    VerticalAlignment="{Binding VerticalImageAlignment}" Stretch="UniformToFill"/>  
  17.         </Grid>  
  18.     </DataTemplate>  
  19.   
  20.     <Style TargetType="ContentControl" x:Key="DefaultHeaderStyle">  
  21.         <Setter Property="HorizontalAlignment" Value="Left"/>  
  22.         <Setter Property="VerticalAlignment" Value="Bottom"/>  
  23.         <Setter Property="Margin" Value="10 5"/>  
  24.         <Setter Property="FontSize" Value="18"/>  
  25.     </Style>  
  26.   
  27.     <Style TargetType="ContentControl" x:Key="DefaultTitleStyle">  
  28.         <Setter Property="HorizontalAlignment" Value="Stretch"/>  
  29.         <Setter Property="VerticalAlignment" Value="Top"/>  
  30.         <Setter Property="Margin" Value="5"/>  
  31.         <Setter Property="FontSize" Value="10"/>  
  32.     </Style>  
  33.   
  34.     <Style TargetType="PulsingTile:PulsingTile" >  
  35.         <Setter Property="Padding" Value="3"/>  
  36.         <Setter Property="HorizontalContentAlignment" Value="Stretch"/>  
  37.         <Setter Property="VerticalContentAlignment" Value="Stretch"/>  
  38.         <Setter Property="HeaderStyle" Value="{StaticResource DefaultHeaderStyle}"/>  
  39.         <Setter Property="TitleStyle" Value="{StaticResource DefaultTitleStyle}"/>  
  40.         <Setter Property="Template">  
  41.             <Setter.Value>  
  42.                 <ControlTemplate TargetType="PulsingTile:PulsingTile">  
  43.                     <Grid x:Name="PART_Layout">  
  44.                         <VisualStateManager.VisualStateGroups>  
  45.                             <VisualStateGroup x:Name="CommonStates">  
  46.                                 <VisualState x:Name="Normal"/>  
  47.                                 <VisualState x:Name="PointerOver">  
  48.                                     <Storyboard>  
  49.                                         <DoubleAnimation Duration="0" To="0.28"   
  50.                                                          Storyboard.TargetProperty="Opacity"   
  51.                                                          Storyboard.TargetName="PointerOveRect"/>  
  52.                                     </Storyboard>  
  53.                                 </VisualState>  
  54.                                 <VisualState x:Name="PointerPressed">  
  55.   
  56.                                 </VisualState>  
  57.                             </VisualStateGroup>  
  58.                         </VisualStateManager.VisualStateGroups>  
  59.   
  60.                         <Rectangle x:Name="PointerOveRect"  
  61.                                    Fill="{StaticResource ApplicationForegroundThemeBrush}"  
  62.                                    Opacity="0" Margin="-2"/>  
  63.   
  64.                         <Border BorderBrush="{TemplateBinding BorderBrush}"   
  65.                                 BorderThickness="{TemplateBinding BorderThickness}"  
  66.                                 Background="{TemplateBinding Background}" Margin="{TemplateBinding Padding}"  
  67.                                 x:Name="PART_Border">  
  68.                             <Grid Margin="{TemplateBinding Padding}" >  
  69.                                 <ContentPresenter     
  70.                                     x:Name="PART_Content"   
  71.                                     HorizontalAlignment="{TemplateBinding HorizontalAlignment}"   
  72.                                     VerticalAlignment="{TemplateBinding VerticalAlignment}" />  
  73.   
  74.                                 <ContentControl Content="{TemplateBinding Title}"  
  75.                                         Style="{TemplateBinding TitleStyle}"/>  
  76.                                 <ContentControl Content="{TemplateBinding Header}"   
  77.                                         Style="{TemplateBinding HeaderStyle}"  
  78.                                         ContentTemplate="{TemplateBinding HeaderTemplate}"   
  79.                                         ContentTemplateSelector="{TemplateBinding HeaderTemplateSelector}"  
  80.                                         />  
  81.                             </Grid>  
  82.                         </Border>  
  83.                     </Grid>  
  84.                 </ControlTemplate>  
  85.             </Setter.Value>  
  86.         </Setter>  
  87.     </Style>  
  88. </ResourceDictionary>  
  89.   
  90.       


 

以上是主体代码。可以将其复制到项目中编译后可用。

使用方式:

  1. <tools:PulsingTile   
  2.        HorizontalAlignment="Stretch"  
  3.        Width="423423"  
  4.        Height="43423"  
  5.        d:DesignWidth="200"  
  6.        d:DesignHeight="200"  
  7.        Foreground="White"       
  8.        RadiusX="0"  
  9.        RadiusY="0"  
  10.        Title="123123123123"  
  11.        PulseDuration="0:0:5"  
  12.        PulseScale="2"  
  13.        VerticalAlignment="Stretch">  
  14.        <Image Source="XXXXXXXXXXXXXXXXX"></Image>  
  15.    </tools:PulsingTile>  


 

最终效果:  该磁贴会根据 时间 放大倍数 等参数 定时脉冲缩放

原文地址:https://www.cnblogs.com/CharlesGrant/p/3639224.html