| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Media;
- using System.Windows.Media.Animation;
- namespace Muchinfo.WPF.Controls.Animation
- {
- /// <summary>
- /// Class RollOverAnimation.
- /// </summary>
- [TemplatePart(Name = "NextItems", Type = typeof(ItemsControl))]
- [TemplatePart(Name = "CurrentItems", Type = typeof(ItemsControl))]
- public class RollOverAnimation : Control
- {
- static RollOverAnimation()
- {
- DefaultStyleKeyProperty.OverrideMetadata(typeof(RollOverAnimation), new FrameworkPropertyMetadata(typeof(RollOverAnimation)));
- }
- private const int C_steySeconds = 3;
- private const int C_PlaySeconds = 5;
- private Storyboard _rolloverStoryboard = new Storyboard();
- private DoubleAnimationUsingKeyFrames _currentAnimation;
- private DoubleAnimationUsingKeyFrames _nextAnimation;
- private ItemsControl _currentItems, _nextItems;
- /// <summary>
- /// 当前索引
- /// </summary>
- public int _currentIndex;
- public RollOverAnimation()
- {
- _currentAnimation = new DoubleAnimationUsingKeyFrames();
- _nextAnimation = new DoubleAnimationUsingKeyFrames();
- _rolloverStoryboard.Completed += _rolloverStoryboard_Completed;
- IsVisibleChanged += delegate(object sender, DependencyPropertyChangedEventArgs e)
- {
- if (false.Equals(e.NewValue))
- {
- _rolloverStoryboard.Stop(this);
- }
- };
- }
- /// <summary>
- /// 动画完成后切换
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- void _rolloverStoryboard_Completed(object sender, EventArgs e)
- {
- _rolloverStoryboard.Stop(this);
- PlayNextList();
- _rolloverStoryboard.Begin(this, true);
- }
- /// <summary>
- /// 显示行的样式
- /// </summary>
- public DataTemplate ItemsTemplate
- {
- get { return (DataTemplate)GetValue(ItemsTemplateProperty); }
- set { SetValue(ItemsTemplateProperty, value); }
- }
- // Using a DependencyProperty as the backing store for ItemsTemplate. This enables animation, styling, binding, etc...
- public static readonly DependencyProperty ItemsTemplateProperty =
- DependencyProperty.Register("ItemsTemplate", typeof(DataTemplate), typeof(RollOverAnimation), new PropertyMetadata(null));
- /// <summary>
- /// 绑定的数据源
- /// </summary>
- public IList ItemsSource
- {
- get { return (IList)GetValue(ItemsSourceProperty); }
- set { SetValue(ItemsSourceProperty, value); }
- }
- // Using a DependencyProperty as the backing store for ItemsSource. This enables animation, styling, binding, etc...
- public static readonly DependencyProperty ItemsSourceProperty =
- DependencyProperty.Register("ItemsSource", typeof(IList), typeof(RollOverAnimation), new PropertyMetadata(null, OnItemsSourceChange));
- /// <summary>
- /// 当前显示的项
- /// </summary>
- public IList CurrentList
- {
- get { return (IList)GetValue(CurrentListProperty); }
- set { SetValue(CurrentListProperty, value); }
- }
- // Using a DependencyProperty as the backing store for CurrentList. This enables animation, styling, binding, etc...
- public static readonly DependencyProperty CurrentListProperty =
- DependencyProperty.Register("CurrentList", typeof(IList), typeof(RollOverAnimation), new PropertyMetadata(null));
- /// <summary>
- /// 即将显示的项
- /// </summary>
- public IList NextList
- {
- get { return (IList)GetValue(NextListProperty); }
- set { SetValue(NextListProperty, value); }
- }
- // Using a DependencyProperty as the backing store for NextList. This enables animation, styling, binding, etc...
- public static readonly DependencyProperty NextListProperty =
- DependencyProperty.Register("NextList", typeof(IList), typeof(RollOverAnimation), new PropertyMetadata(null));
- /// <summary>
- /// 每次显示的数量
- /// </summary>
- public int ShowCount
- {
- get { return (int)GetValue(ShowCountProperty); }
- set { SetValue(ShowCountProperty, value); }
- }
- // Using a DependencyProperty as the backing store for ShowIndex. This enables animation, styling, binding, etc...
- public static readonly DependencyProperty ShowCountProperty =
- DependencyProperty.Register("ShowCount", typeof(int), typeof(RollOverAnimation), new PropertyMetadata(3));
- /// <summary>
- /// 当数据源改变时重新进行动画
- /// </summary>
- /// <param name="d"></param>
- /// <param name="e"></param>
- public static void OnItemsSourceChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- var self = d as RollOverAnimation;
- if (self != null)
- {
- self.InitSourceAndPlay();
- }
- }
- /// <summary>
- /// 初始化数据并运行动画
- /// </summary>
- private void InitSourceAndPlay()
- {
- if (ItemsSource != null && ItemsSource.Count > 0)
- {
- _rolloverStoryboard.Stop(this);
- _currentIndex = 0;
- if (ItemsSource.Count > ShowCount)
- {
- var list = new List<object>();
- var nextlist = new List<object>();
- int nextIndex = ShowCount;
- for (int i = 0; i < ShowCount; i++)
- {
- list.Add(ItemsSource[i]);
- if (nextIndex < ItemsSource.Count)
- {
- nextlist.Add(ItemsSource[nextIndex]);
- nextIndex++;
- }
- }
- _currentIndex = ShowCount - 1;
- CurrentList = list;
- NextList = nextlist;
- _rolloverStoryboard.Begin(this, true);
- }
- else
- {
- CurrentList = ItemsSource;
- }
- }
- }
- /// <summary>
- /// 播放一下个动画
- /// </summary>
- private void PlayNextList()
- {
- if (ItemsSource != null)
- {
- CurrentList = NextList;
- int tempflag = _currentIndex + NextList.Count;
- _currentIndex = tempflag > ItemsSource.Count - 1 ? NextList.Count - 1 : tempflag;
- //if (_currentIndex >= ItemsSource.Count-1)
- //{
- // _currentIndex = 0;
- //}
- tempflag = _currentIndex >= ItemsSource.Count - 1 ? 0 : _currentIndex + 1;
- var nextList = new List<object>();
- for (int i = tempflag; i < tempflag + ShowCount; i++)
- {
- if (i < ItemsSource.Count)
- {
- nextList.Add(ItemsSource[i]);
- }
- }
- NextList = nextList;
- }
- }
- public override void OnApplyTemplate()
- {
- _currentItems = GetTemplateChild("CurrentItems") as ItemsControl;
- _nextItems = GetTemplateChild("NextItems") as ItemsControl;
- base.OnApplyTemplate();
- }
- protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
- {
- if (_currentItems != null && _nextItems != null)
- {
- _currentAnimation.KeyFrames.Clear();
- _currentAnimation.KeyFrames.Add(new EasingDoubleKeyFrame(0, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0))));
- _currentAnimation.KeyFrames.Add(new EasingDoubleKeyFrame(0, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(C_steySeconds))));
- _currentAnimation.KeyFrames.Add(new EasingDoubleKeyFrame(-this.ActualHeight, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(C_PlaySeconds))));
- _nextAnimation.KeyFrames.Clear();
- _nextAnimation.KeyFrames.Add(new EasingDoubleKeyFrame(this.ActualHeight, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0))));
- _nextAnimation.KeyFrames.Add(new EasingDoubleKeyFrame(this.ActualHeight, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(C_steySeconds))));
- _nextAnimation.KeyFrames.Add(new EasingDoubleKeyFrame(0, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(C_PlaySeconds))));
- Storyboard.SetTarget(_currentAnimation, _currentItems);
- Storyboard.SetTargetProperty(_currentAnimation, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.Y)"));
- Storyboard.SetTarget(_nextAnimation, _nextItems);
- Storyboard.SetTargetProperty(_nextAnimation, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.Y)"));
- _rolloverStoryboard.Children.Add(_currentAnimation);
- _rolloverStoryboard.Children.Add(_nextAnimation);
- this.Clip = new RectangleGeometry(new Rect(new Point(), new Size(this.ActualWidth, this.ActualHeight)));
- }
- base.OnRenderSizeChanged(sizeInfo);
- }
- }
- }
|