WPF轮播图实现方式
生活随笔
收集整理的這篇文章主要介紹了
WPF轮播图实现方式
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
?WPF開發(fā)者QQ群:?340500857? | 微信群 -> 進入公眾號主頁?加入組織
歡迎轉(zhuǎn)發(fā)、分享、點贊、在看,謝謝~。??
01
—
效果預(yù)覽
效果預(yù)覽(更多效果請下載源碼體驗):
02
—
代碼如下
一、MasterCarousel.cs 代碼如下
using System; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.ComponentModel; using System.Timers; using System.Windows; using System.Windows.Controls; using System.Windows.Markup; using System.Windows.Media; using System.Windows.Media.Animation; using WPFDevelopers.Controls.Helpers;namespace WPFDevelopers.Controls {internal enum CarouselLoacation{Left,Right,Center}internal enum CarouselZIndex{Left = 20,Center = 30,Right = 20,LeftMask = 40,RightMask = 40}[DefaultProperty("Children")][ContentProperty("Children")][Localizability(LocalizationCategory.None, Readability = Readability.Unreadable)][TemplatePart(Name = Part_ContentDockName, Type = typeof(Canvas))][TemplatePart(Name = Part_ButtonDockName, Type = typeof(StackPanel))]public class MasterCarousel : Control, IAddChild{private const string Part_ContentDockName = "PART_ContentDock";private const string Part_ButtonDockName = "PART_ButtonDock";static MasterCarousel(){DefaultStyleKeyProperty.OverrideMetadata(typeof(MasterCarousel), new FrameworkPropertyMetadata(typeof(MasterCarousel)));}public MasterCarousel(){//_uiElementCollection = new List<object>();//SizeChanged += MasterCarousel_SizeChanged;LoadeTimer();Loaded += MasterCarousel_Loaded;}#region feildbool _isLoaded = false;Canvas _Part_ContentDock;StackPanel _Part_ButtonDock;#endregion#region render relativeconst double _ScaleRatio = 0.95;const double _ScaleRatioEx = 1;const double _CycleInterval = 2000;double _ShellWidth = 0;double _ShellHeight = 0;double _ElementWidth = 0;double _ElementHeight = 0;double _ElementScale = 0.6;double _CenterDockLeft = 0;double _LeftDockLeft = 0;double _RightDockLeft = 0;double _DockOffset = 0.2;int _CarouselSize = 0;#endregion#regionDictionary<int, object> _mapResources = new Dictionary<int, object>();Dictionary<int, FrameworkElement> _mapFrameworkes = new Dictionary<int, FrameworkElement>();Dictionary<CarouselLoacation, int> _mapCarouselLocationFramewokes = new Dictionary<CarouselLoacation, int>();LinkedList<int> _BufferLinkedList = new LinkedList<int>();#endregion#region timerTimer _PlayTimer = new Timer();#endregion#region StoryBoardStoryboard _Storyboard = null;double _AnimationTime = 0.5;double _DelayAnimationTime = 0.7;bool _IsAinimationStart = false;bool _IsStoryboardWorking = false;#endregion#region overridepublic override void OnApplyTemplate(){base.OnApplyTemplate();_Part_ContentDock = GetTemplateChild(Part_ContentDockName) as Canvas;_Part_ButtonDock = GetTemplateChild(Part_ButtonDockName) as StackPanel;if (_Part_ContentDock == null || _Part_ButtonDock == null)throw new Exception("Some element is not in template!");}#endregionpublic bool IsStartAinimation{get { return (bool)GetValue(IsStartAinimationProperty); }set { SetValue(IsStartAinimationProperty, value); }}// Using a DependencyProperty as the backing store for IsStartAinimation. This enables animation, styling, binding, etc...public static readonly DependencyProperty IsStartAinimationProperty =DependencyProperty.Register("IsStartAinimation", typeof(bool), typeof(MasterCarousel), new PropertyMetadata(default(bool), OnIsStartAinimationPropertyChangedCallback));private static void OnIsStartAinimationPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e){if (d == null)return;if (!(d is MasterCarousel control))return;if (bool.TryParse(e.NewValue?.ToString(), out bool bResult)){if (bResult)control.Start();elsecontrol.Stop();}}public IEnumerable ItemsSource{get { return (IEnumerable)GetValue(ItemsSourceProperty); }set { SetValue(ItemsSourceProperty, value); }}// Using a DependencyProperty as the backing store for Childrens. This enables animation, styling, binding, etc...public static readonly DependencyProperty ItemsSourceProperty =DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(MasterCarousel), new PropertyMetadata(default(IEnumerable), OnItemsSourcePropertyChangedCallBack));private static void OnItemsSourcePropertyChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e){if (!(d is MasterCarousel carousel))return;var vOldEvent = e.OldValue?.GetType()?.GetEvent("CollectionChanged");if (vOldEvent != null)vOldEvent.RemoveEventHandler(e.OldValue, new NotifyCollectionChangedEventHandler(carousel.ChildrenPropertyChanged));var vEvent = e.NewValue?.GetType()?.GetEvent("CollectionChanged");if (vEvent != null)vEvent.AddEventHandler(e.NewValue, new NotifyCollectionChangedEventHandler(carousel.ChildrenPropertyChanged));}void ChildrenPropertyChanged(object sender, NotifyCollectionChangedEventArgs e){switch (e.Action){case NotifyCollectionChangedAction.Add:break;case NotifyCollectionChangedAction.Remove:break;case NotifyCollectionChangedAction.Replace:break;case NotifyCollectionChangedAction.Move:break;case NotifyCollectionChangedAction.Reset:break;default:break;}}List<object> _uiElementCollection = new List<object>();[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]public List<object> Children => _uiElementCollection;public void AddChild(object value){throw new NotImplementedException();}public void AddText(string text){throw new NotImplementedException();}bool LoadeTimer(){_PlayTimer.Interval = _CycleInterval;_PlayTimer.Elapsed += PlayTimer_Elapsed;return true;}bool CalculationShellReletiveProperty(){//計算當(dāng)前目標(biāo)區(qū)域的尺寸if (_Part_ContentDock == null)return false;var vWidth = _Part_ContentDock.ActualWidth;var vHeight = _Part_ContentDock.ActualHeight;if (vWidth == 0 || vHeight == 0)return false;if (vWidth == _ShellWidth && vHeight == _ShellHeight)return false;_ShellWidth = vWidth;_ShellHeight = vHeight;//計算 元素的默認長度和寬度_ElementWidth = _ShellWidth * _ElementScale;_ElementHeight = _ShellHeight;_LeftDockLeft = 0;_CenterDockLeft = 0 + _ShellWidth * _DockOffset;_RightDockLeft = _ShellWidth - _ElementWidth;return true;}bool LoadCarousel(){if (Children.Count <= 0 && ItemsSource == null)return false;if (_Part_ButtonDock != null){foreach (var item in _Part_ButtonDock.Children){if (item is FrameworkElement frameworkElement){frameworkElement.MouseEnter -= Border_MouseEnter;frameworkElement.PreviewMouseDown -= Border_PreviewMouseDown;}}}_mapFrameworkes.Clear();_mapCarouselLocationFramewokes.Clear();_BufferLinkedList.Clear();_Part_ContentDock?.Children.Clear();_Part_ButtonDock?.Children.Clear();if (Children.Count > 0){_CarouselSize = Children.Count;for (int i = 0; i < _CarouselSize; i++){var vItem = Children[i];FrameworkElement frameworkElement;if (vItem is FrameworkElement)frameworkElement = vItem as FrameworkElement;else{var vContent = new ContentControl();vContent.HorizontalContentAlignment = HorizontalAlignment.Center;vContent.VerticalContentAlignment = VerticalAlignment.Center;vContent.Content = vItem;frameworkElement = vContent;}frameworkElement.Width = _ElementWidth;frameworkElement.Height = _ElementHeight;frameworkElement.RenderTransformOrigin = new Point(0.5, 1);var vTransformGroup = new TransformGroup{Children ={new ScaleTransform(){ ScaleY = _ScaleRatio},new SkewTransform(),new RotateTransform(),new TranslateTransform()}};frameworkElement.RenderTransform = vTransformGroup;Border border = new Border(){Margin = new Thickness(5),Width = 20,Height = 6,//CornerRadius = new CornerRadius(20),Background = Brushes.Gray,Tag = i,};border.MouseEnter += Border_MouseEnter;border.PreviewMouseDown += Border_PreviewMouseDown;_mapResources[i] = vItem;_mapFrameworkes[i] = frameworkElement;_Part_ContentDock?.Children.Add(frameworkElement);_Part_ButtonDock?.Children.Add(border);//第一個元素居中并且放大顯示if (i == 0){var vScaleTransform = vTransformGroup.Children[0] as ScaleTransform;vScaleTransform.ScaleY = _ScaleRatioEx;frameworkElement.SetValue(Canvas.LeftProperty, _CenterDockLeft);Panel.SetZIndex(frameworkElement, (int)CarouselZIndex.Center);_mapCarouselLocationFramewokes.Add(CarouselLoacation.Center, i);}else if (i == 1){frameworkElement.SetValue(Canvas.LeftProperty, _RightDockLeft);Panel.SetZIndex(frameworkElement, (int)CarouselZIndex.Right);_mapCarouselLocationFramewokes.Add(CarouselLoacation.Right, i);}else if (i == _CarouselSize - 1){frameworkElement.SetValue(Canvas.LeftProperty, _LeftDockLeft);Panel.SetZIndex(frameworkElement, (int)CarouselZIndex.Left);_mapCarouselLocationFramewokes.Add(CarouselLoacation.Left, i);}else{_BufferLinkedList.AddLast(i);frameworkElement.SetValue(Canvas.LeftProperty, _CenterDockLeft);Panel.SetZIndex(frameworkElement, i);}}}else{_CarouselSize = ItemsSource.Count();int nIndex = 0;foreach (var item in ItemsSource){FrameworkElement frameworkElement;if (item is FrameworkElement)frameworkElement = item as FrameworkElement;else{var vContent = new ContentControl();vContent.HorizontalContentAlignment = HorizontalAlignment.Center;vContent.VerticalContentAlignment = VerticalAlignment.Center;vContent.Content = item;frameworkElement = vContent;}frameworkElement.Width = _ElementWidth;frameworkElement.Height = _ElementHeight;frameworkElement.RenderTransformOrigin = new Point(0.5, 1);var vTransformGroup = new TransformGroup{Children ={new ScaleTransform(){ ScaleY = _ScaleRatio},new SkewTransform(),new RotateTransform(),new TranslateTransform()}};frameworkElement.RenderTransform = vTransformGroup;Border border = new Border(){Width = 25,Height = 25,CornerRadius = new CornerRadius(25),Background = Brushes.Gray,Tag = nIndex,};border.MouseEnter += Border_MouseEnter;border.PreviewMouseDown += Border_PreviewMouseDown;_mapResources[nIndex] = item;_mapFrameworkes[nIndex] = frameworkElement;_Part_ContentDock?.Children.Add(frameworkElement);_Part_ButtonDock?.Children.Add(border);//第一個元素居中并且放大顯示if (nIndex == 0){var vScaleTransform = vTransformGroup.Children[0] as ScaleTransform;vScaleTransform.ScaleY = _ScaleRatioEx;frameworkElement.SetValue(Canvas.LeftProperty, _CenterDockLeft);Panel.SetZIndex(frameworkElement, (int)CarouselZIndex.Center);_mapCarouselLocationFramewokes.Add(CarouselLoacation.Center, nIndex);}else if (nIndex == 1){frameworkElement.SetValue(Canvas.LeftProperty, _RightDockLeft);Panel.SetZIndex(frameworkElement, (int)CarouselZIndex.Right);_mapCarouselLocationFramewokes.Add(CarouselLoacation.Right, nIndex);}else if (nIndex == _CarouselSize - 1){frameworkElement.SetValue(Canvas.LeftProperty, _LeftDockLeft);Panel.SetZIndex(frameworkElement, (int)CarouselZIndex.Left);_mapCarouselLocationFramewokes.Add(CarouselLoacation.Left, nIndex);}else{_BufferLinkedList.AddLast(nIndex);frameworkElement.SetValue(Canvas.LeftProperty, _CenterDockLeft);Panel.SetZIndex(frameworkElement, nIndex);}}}return true;}#region 動畫//從左邊向右依次播放bool PlayCarouselLeftToRight(){if (_Storyboard == null){_Storyboard = new Storyboard();_Storyboard.Completed += Storyboard_Completed;}if (_IsStoryboardWorking)return false;_IsStoryboardWorking = true;_Storyboard?.Children.Clear();int nNextIndex = -1;//右邊的動畫移動到中間 后層{var vResult = _mapCarouselLocationFramewokes.GetValueOrDefault(CarouselLoacation.Right, -1);var vFrameworker = _mapFrameworkes.GetValueOrDefault(vResult, null);if (vFrameworker != null){//置于后層Int32Animation animation1 = new Int32Animation{To = vResult + 1,Duration = TimeSpan.FromSeconds(_DelayAnimationTime),EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation1, vFrameworker);Storyboard.SetTargetProperty(animation1, new PropertyPath("(Panel.ZIndex)"));_Storyboard.Children.Add(animation1);//右邊移動到中間DoubleAnimation animation2 = new DoubleAnimation{To = _CenterDockLeft,Duration = TimeSpan.FromSeconds(_AnimationTime),EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation2, vFrameworker);Storyboard.SetTargetProperty(animation2, new PropertyPath("(Canvas.Left)"));_Storyboard.Children.Add(animation2);//縮放DoubleAnimation animation3 = new DoubleAnimation(){Duration = TimeSpan.FromSeconds(_AnimationTime),To = _ScaleRatio,EasingFunction = new ExponentialEase() { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation3, vFrameworker);Storyboard.SetTargetProperty(animation3, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"));_Storyboard.Children.Add(animation3);_BufferLinkedList.AddFirst(vResult);}_mapCarouselLocationFramewokes[CarouselLoacation.Right] = -1;}//中間的動畫移動到右邊{var vResult = _mapCarouselLocationFramewokes.GetValueOrDefault(CarouselLoacation.Center, -1);var vFrameworker = _mapFrameworkes.GetValueOrDefault(vResult, null);if (vFrameworker != null){//置于左邊上層Int32Animation animation1 = new Int32Animation{To = (int)CarouselZIndex.Right,Duration = TimeSpan.FromSeconds(_DelayAnimationTime),EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation1, vFrameworker);Storyboard.SetTargetProperty(animation1, new PropertyPath("(Panel.ZIndex)"));_Storyboard.Children.Add(animation1);//從中間到左邊DoubleAnimation animation2 = new DoubleAnimation{//BeginTime = TimeSpan.FromSeconds(_DelayAnimationTime),To = _RightDockLeft,Duration = TimeSpan.FromSeconds(_AnimationTime),EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation2, vFrameworker);Storyboard.SetTargetProperty(animation2, new PropertyPath("(Canvas.Left)"));_Storyboard.Children.Add(animation2);//縮放DoubleAnimation animation3 = new DoubleAnimation(){Duration = TimeSpan.FromSeconds(_AnimationTime),To = _ScaleRatio,EasingFunction = new ExponentialEase() { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation3, vFrameworker);Storyboard.SetTargetProperty(animation3, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"));_Storyboard.Children.Add(animation3);_mapCarouselLocationFramewokes[CarouselLoacation.Right] = vResult;}_mapCarouselLocationFramewokes[CarouselLoacation.Center] = -1;}//左邊的動畫移動到中間 上層{var vResult = _mapCarouselLocationFramewokes.GetValueOrDefault(CarouselLoacation.Left, -1);var vFrameworker = _mapFrameworkes.GetValueOrDefault(vResult, null);if (vFrameworker != null){//置于上層Int32Animation animation1 = new Int32Animation{To = (int)CarouselZIndex.Center,Duration = TimeSpan.FromSeconds(_DelayAnimationTime),EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation1, vFrameworker);Storyboard.SetTargetProperty(animation1, new PropertyPath("(Panel.ZIndex)"));_Storyboard.Children.Add(animation1);//從左到中DoubleAnimation animation2 = new DoubleAnimation{To = _CenterDockLeft,Duration = TimeSpan.FromSeconds(_AnimationTime),EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation2, vFrameworker);Storyboard.SetTargetProperty(animation2, new PropertyPath("(Canvas.Left)"));_Storyboard.Children.Add(animation2);//縮放DoubleAnimation animation3 = new DoubleAnimation(){Duration = TimeSpan.FromSeconds(_AnimationTime),To = _ScaleRatioEx,EasingFunction = new ExponentialEase() { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation3, vFrameworker);Storyboard.SetTargetProperty(animation3, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"));_Storyboard.Children.Add(animation3);_mapCarouselLocationFramewokes[CarouselLoacation.Center] = vResult;nNextIndex = vResult - 1;if (nNextIndex < 0)nNextIndex = _CarouselSize - 1;}_mapCarouselLocationFramewokes[CarouselLoacation.Left] = -1;}//后層記錄推送到前臺左側(cè)if (nNextIndex >= 0){_BufferLinkedList.Remove(nNextIndex);var vFrameworker = _mapFrameworkes.GetValueOrDefault(nNextIndex, null);if (vFrameworker != null){//右側(cè)置頂Int32Animation animation1 = new Int32Animation{To = (int)CarouselZIndex.Left,Duration = TimeSpan.FromSeconds(_DelayAnimationTime),EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation1, vFrameworker);Storyboard.SetTargetProperty(animation1, new PropertyPath("(Panel.ZIndex)"));_Storyboard.Children.Add(animation1);//從中間移動到右側(cè)DoubleAnimation animation2 = new DoubleAnimation{To = _LeftDockLeft,Duration = TimeSpan.FromSeconds(_AnimationTime),EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation2, vFrameworker);Storyboard.SetTargetProperty(animation2, new PropertyPath("(Canvas.Left)"));_Storyboard.Children.Add(animation2);DoubleAnimation animation3 = new DoubleAnimation(){Duration = TimeSpan.FromSeconds(_AnimationTime),To = _ScaleRatio,EasingFunction = new ExponentialEase() { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation3, vFrameworker);Storyboard.SetTargetProperty(animation3, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"));_Storyboard.Children.Add(animation3);_mapCarouselLocationFramewokes[CarouselLoacation.Left] = nNextIndex;}}else{if (_BufferLinkedList.Count > 0){var vResult = _BufferLinkedList.LastOrDefault();_BufferLinkedList.RemoveLast();var vFrameworker = _mapFrameworkes.GetValueOrDefault(vResult, null);if (vFrameworker != null){//右側(cè)置頂Int32Animation animation1 = new Int32Animation{To = (int)CarouselZIndex.Left,Duration = TimeSpan.FromSeconds(_DelayAnimationTime),EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation1, vFrameworker);Storyboard.SetTargetProperty(animation1, new PropertyPath("(Panel.ZIndex)"));_Storyboard.Children.Add(animation1);//從中間移動到右側(cè)DoubleAnimation animation2 = new DoubleAnimation{To = _LeftDockLeft,Duration = TimeSpan.FromSeconds(_AnimationTime),EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation2, vFrameworker);Storyboard.SetTargetProperty(animation2, new PropertyPath("(Canvas.Left)"));_Storyboard.Children.Add(animation2);DoubleAnimation animation3 = new DoubleAnimation(){Duration = TimeSpan.FromSeconds(_AnimationTime),To = _ScaleRatio,EasingFunction = new ExponentialEase() { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation3, vFrameworker);Storyboard.SetTargetProperty(animation3, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"));_Storyboard.Children.Add(animation3);_mapCarouselLocationFramewokes[CarouselLoacation.Left] = vResult;}}}_Storyboard?.Begin();return true;}//從右向左依次播放bool PlayCarouselRightToLeft(){if (_Storyboard == null){_Storyboard = new Storyboard();_Storyboard.Completed += Storyboard_Completed;}_IsStoryboardWorking = true;_Storyboard?.Children.Clear();int nNextIndex = -1;//左邊的動畫移動到中間 后層{var vResult = _mapCarouselLocationFramewokes.GetValueOrDefault(CarouselLoacation.Left, -1);var vFrameworker = _mapFrameworkes.GetValueOrDefault(vResult, null);if (vFrameworker != null){//置于后層Int32Animation animation1 = new Int32Animation{To = vResult + 1,Duration = TimeSpan.FromSeconds(_DelayAnimationTime),EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation1, vFrameworker);Storyboard.SetTargetProperty(animation1, new PropertyPath("(Panel.ZIndex)"));_Storyboard.Children.Add(animation1);//從左到中DoubleAnimation animation2 = new DoubleAnimation{To = _CenterDockLeft,Duration = TimeSpan.FromSeconds(_AnimationTime),EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation2, vFrameworker);Storyboard.SetTargetProperty(animation2, new PropertyPath("(Canvas.Left)"));_Storyboard.Children.Add(animation2);//縮放DoubleAnimation animation3 = new DoubleAnimation(){Duration = TimeSpan.FromSeconds(_AnimationTime),To = _ScaleRatio,EasingFunction = new ExponentialEase() { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation3, vFrameworker);Storyboard.SetTargetProperty(animation3, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"));_Storyboard.Children.Add(animation3);_BufferLinkedList.AddLast(vResult);}_mapCarouselLocationFramewokes[CarouselLoacation.Left] = -1;}//中間的動畫移動到左邊{var vResult = _mapCarouselLocationFramewokes.GetValueOrDefault(CarouselLoacation.Center, -1);var vFrameworker = _mapFrameworkes.GetValueOrDefault(vResult, null);if (vFrameworker != null){//置于左邊上層Int32Animation animation1 = new Int32Animation{To = (int)CarouselZIndex.Left,Duration = TimeSpan.FromSeconds(_DelayAnimationTime),EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation1, vFrameworker);Storyboard.SetTargetProperty(animation1, new PropertyPath("(Panel.ZIndex)"));_Storyboard.Children.Add(animation1);//從中間到左邊DoubleAnimation animation2 = new DoubleAnimation{//BeginTime = TimeSpan.FromSeconds(_DelayAnimationTime),To = _LeftDockLeft,Duration = TimeSpan.FromSeconds(_AnimationTime),EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation2, vFrameworker);Storyboard.SetTargetProperty(animation2, new PropertyPath("(Canvas.Left)"));_Storyboard.Children.Add(animation2);//縮放DoubleAnimation animation3 = new DoubleAnimation(){Duration = TimeSpan.FromSeconds(_AnimationTime),To = _ScaleRatio,EasingFunction = new ExponentialEase() { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation3, vFrameworker);Storyboard.SetTargetProperty(animation3, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"));_Storyboard.Children.Add(animation3);_mapCarouselLocationFramewokes[CarouselLoacation.Left] = vResult;}_mapCarouselLocationFramewokes[CarouselLoacation.Center] = -1;}//右邊的動畫移動到中間{var vResult = _mapCarouselLocationFramewokes.GetValueOrDefault(CarouselLoacation.Right, -1);var vFrameworker = _mapFrameworkes.GetValueOrDefault(vResult, null);if (vFrameworker != null){//置于上層Int32Animation animation1 = new Int32Animation{To = (int)CarouselZIndex.Center,Duration = TimeSpan.FromSeconds(_DelayAnimationTime),EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation1, vFrameworker);Storyboard.SetTargetProperty(animation1, new PropertyPath("(Panel.ZIndex)"));_Storyboard.Children.Add(animation1);//右邊移動到中間DoubleAnimation animation2 = new DoubleAnimation{To = _CenterDockLeft,Duration = TimeSpan.FromSeconds(_AnimationTime),EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation2, vFrameworker);Storyboard.SetTargetProperty(animation2, new PropertyPath("(Canvas.Left)"));_Storyboard.Children.Add(animation2);//縮放DoubleAnimation animation3 = new DoubleAnimation(){Duration = TimeSpan.FromSeconds(_AnimationTime),To = _ScaleRatioEx,EasingFunction = new ExponentialEase() { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation3, vFrameworker);Storyboard.SetTargetProperty(animation3, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"));_Storyboard.Children.Add(animation3);_mapCarouselLocationFramewokes[CarouselLoacation.Center] = vResult;nNextIndex = vResult + 1;if (nNextIndex >= _CarouselSize)nNextIndex = 0;}_mapCarouselLocationFramewokes[CarouselLoacation.Right] = -1;}//后層記錄推送到前臺if (nNextIndex >= 0){_BufferLinkedList.Remove(nNextIndex);var vFrameworker = _mapFrameworkes.GetValueOrDefault(nNextIndex, null);if (vFrameworker != null){//右側(cè)置頂Int32Animation animation1 = new Int32Animation{To = (int)CarouselZIndex.Right,Duration = TimeSpan.FromSeconds(_DelayAnimationTime),EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation1, vFrameworker);Storyboard.SetTargetProperty(animation1, new PropertyPath("(Panel.ZIndex)"));_Storyboard.Children.Add(animation1);//從中間移動到右側(cè)DoubleAnimation animation2 = new DoubleAnimation{To = _RightDockLeft,Duration = TimeSpan.FromSeconds(_AnimationTime),EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation2, vFrameworker);Storyboard.SetTargetProperty(animation2, new PropertyPath("(Canvas.Left)"));_Storyboard.Children.Add(animation2);DoubleAnimation animation3 = new DoubleAnimation(){Duration = TimeSpan.FromSeconds(_AnimationTime),To = _ScaleRatio,EasingFunction = new ExponentialEase() { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation3, vFrameworker);Storyboard.SetTargetProperty(animation3, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"));_Storyboard.Children.Add(animation3);_mapCarouselLocationFramewokes[CarouselLoacation.Right] = nNextIndex;}}else{if (_BufferLinkedList.Count > 0){var vResult = _BufferLinkedList.FirstOrDefault();_BufferLinkedList.RemoveFirst();var vFrameworker = _mapFrameworkes.GetValueOrDefault(vResult, null);if (vFrameworker != null){//右側(cè)置頂Int32Animation animation1 = new Int32Animation{To = (int)CarouselZIndex.Right,Duration = TimeSpan.FromSeconds(_DelayAnimationTime),EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation1, vFrameworker);Storyboard.SetTargetProperty(animation1, new PropertyPath("(Panel.ZIndex)"));_Storyboard.Children.Add(animation1);//從中間移動到右側(cè)DoubleAnimation animation2 = new DoubleAnimation{To = _RightDockLeft,Duration = TimeSpan.FromSeconds(_AnimationTime),EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation2, vFrameworker);Storyboard.SetTargetProperty(animation2, new PropertyPath("(Canvas.Left)"));_Storyboard.Children.Add(animation2);DoubleAnimation animation3 = new DoubleAnimation(){Duration = TimeSpan.FromSeconds(_AnimationTime),To = _ScaleRatio,EasingFunction = new ExponentialEase() { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation3, vFrameworker);Storyboard.SetTargetProperty(animation3, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"));_Storyboard.Children.Add(animation3);_mapCarouselLocationFramewokes[CarouselLoacation.Right] = vResult;}}}_Storyboard?.Begin();return true;}//當(dāng)用戶點擊其中某個位置的動畫時bool PlayCarouselWithIndex(int nIndex){//檢查 nIndex是否有效if (nIndex < 0 || nIndex >= _CarouselSize)return false;//判斷當(dāng)前選中的是否處于中間播放位置{var vResult = _mapCarouselLocationFramewokes.GetValueOrDefault(CarouselLoacation.Center, -1);if (vResult == nIndex)return true;}//判斷如果當(dāng)前選中的在左側(cè)等待區(qū) 播放順序是從左向右{var vResult = _mapCarouselLocationFramewokes.GetValueOrDefault(CarouselLoacation.Left, -1);if (vResult == nIndex)return PlayCarouselLeftToRight();}//判斷如果當(dāng)前選中的在右側(cè)等待區(qū) 播放順序是從右向左{var vResult = _mapCarouselLocationFramewokes.GetValueOrDefault(CarouselLoacation.Right, -1);if (vResult == nIndex)return PlayCarouselRightToLeft();}//其他情況 return PlayCarouselWithIndexOutRange(nIndex);}bool PlayCarouselWithIndexOutRange(int nIndex){//檢查 nIndex是否有效if (nIndex < 0 || nIndex >= _CarouselSize)return false;//計算前后動畫位置var vPre = nIndex - 1;if (vPre < 0)vPre = _CarouselSize - 1;var vNext = nIndex + 1;if (vNext >= _CarouselSize)vNext = 0;if (_Storyboard == null){_Storyboard = new Storyboard();_Storyboard.Completed += Storyboard_Completed;}if (_IsStoryboardWorking)return false;_IsStoryboardWorking = true;_Storyboard?.Children.Clear();//清空隊列_BufferLinkedList.Clear();//先將隊列歸位 全部置于中間后面隱藏{var vResult = _mapCarouselLocationFramewokes.GetValueOrDefault(CarouselLoacation.Right, -1);var vFrameworker = _mapFrameworkes.GetValueOrDefault(vResult, null);if (vFrameworker != null){//置于后層Int32Animation animation1 = new Int32Animation{To = vResult + 1,Duration = TimeSpan.FromSeconds(_DelayAnimationTime),EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation1, vFrameworker);Storyboard.SetTargetProperty(animation1, new PropertyPath("(Panel.ZIndex)"));_Storyboard.Children.Add(animation1);//回到中間DoubleAnimation animation2 = new DoubleAnimation{To = _CenterDockLeft,Duration = TimeSpan.FromSeconds(_AnimationTime),EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation2, vFrameworker);Storyboard.SetTargetProperty(animation2, new PropertyPath("(Canvas.Left)"));_Storyboard.Children.Add(animation2);//縮放DoubleAnimation animation3 = new DoubleAnimation(){Duration = TimeSpan.FromSeconds(_AnimationTime),To = _ScaleRatio,EasingFunction = new ExponentialEase() { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation3, vFrameworker);Storyboard.SetTargetProperty(animation3, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"));_Storyboard.Children.Add(animation3);}_mapCarouselLocationFramewokes[CarouselLoacation.Right] = -1;}{var vResult = _mapCarouselLocationFramewokes.GetValueOrDefault(CarouselLoacation.Center, -1);var vFrameworker = _mapFrameworkes.GetValueOrDefault(vResult, null);if (vFrameworker != null){//置于后層Int32Animation animation1 = new Int32Animation{To = vResult + 1,Duration = TimeSpan.FromSeconds(_DelayAnimationTime),EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation1, vFrameworker);Storyboard.SetTargetProperty(animation1, new PropertyPath("(Panel.ZIndex)"));_Storyboard.Children.Add(animation1);//回到中間DoubleAnimation animation2 = new DoubleAnimation{To = _CenterDockLeft,Duration = TimeSpan.FromSeconds(_AnimationTime),EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation2, vFrameworker);Storyboard.SetTargetProperty(animation2, new PropertyPath("(Canvas.Left)"));_Storyboard.Children.Add(animation2);//縮放DoubleAnimation animation3 = new DoubleAnimation(){Duration = TimeSpan.FromSeconds(_AnimationTime),To = _ScaleRatio,EasingFunction = new ExponentialEase() { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation3, vFrameworker);Storyboard.SetTargetProperty(animation3, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"));_Storyboard.Children.Add(animation3);}_mapCarouselLocationFramewokes[CarouselLoacation.Center] = -1;}{var vResult = _mapCarouselLocationFramewokes.GetValueOrDefault(CarouselLoacation.Left, -1);var vFrameworker = _mapFrameworkes.GetValueOrDefault(vResult, null);if (vFrameworker != null){//置于后層Int32Animation animation1 = new Int32Animation{To = vResult + 1,Duration = TimeSpan.FromSeconds(_DelayAnimationTime),EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation1, vFrameworker);Storyboard.SetTargetProperty(animation1, new PropertyPath("(Panel.ZIndex)"));_Storyboard.Children.Add(animation1);//回到中間DoubleAnimation animation2 = new DoubleAnimation{To = _CenterDockLeft,Duration = TimeSpan.FromSeconds(_AnimationTime),EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation2, vFrameworker);Storyboard.SetTargetProperty(animation2, new PropertyPath("(Canvas.Left)"));_Storyboard.Children.Add(animation2);//縮放DoubleAnimation animation3 = new DoubleAnimation(){Duration = TimeSpan.FromSeconds(_AnimationTime),To = _ScaleRatio,EasingFunction = new ExponentialEase() { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation3, vFrameworker);Storyboard.SetTargetProperty(animation3, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"));_Storyboard.Children.Add(animation3);}_mapCarouselLocationFramewokes[CarouselLoacation.Left] = -1;}//再調(diào)出目標(biāo)位置動畫for (int i = 0; i < _CarouselSize; i++){if (i == vPre) //放左側(cè){if (_mapFrameworkes.ContainsKey(i)){var vFrameworker = _mapFrameworkes.GetValueOrDefault(i, null);if (vFrameworker != null){//置于左邊上層Int32Animation animation1 = new Int32Animation{To = (int)CarouselZIndex.Left,Duration = TimeSpan.FromSeconds(_DelayAnimationTime),EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation1, vFrameworker);Storyboard.SetTargetProperty(animation1, new PropertyPath("(Panel.ZIndex)"));_Storyboard.Children.Add(animation1);//從中間到左邊DoubleAnimation animation2 = new DoubleAnimation{BeginTime = TimeSpan.FromSeconds(_DelayAnimationTime),To = _LeftDockLeft,Duration = TimeSpan.FromSeconds(_AnimationTime),EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation2, vFrameworker);Storyboard.SetTargetProperty(animation2, new PropertyPath("(Canvas.Left)"));_Storyboard.Children.Add(animation2);//縮放DoubleAnimation animation3 = new DoubleAnimation(){Duration = TimeSpan.FromSeconds(_AnimationTime),To = _ScaleRatio,EasingFunction = new ExponentialEase() { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation3, vFrameworker);Storyboard.SetTargetProperty(animation3, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"));_Storyboard.Children.Add(animation3);_mapCarouselLocationFramewokes[CarouselLoacation.Left] = i;}}}else if (i == nIndex) //放中間{if (_mapFrameworkes.ContainsKey(i)){var vFrameworker = _mapFrameworkes.GetValueOrDefault(i, null);if (vFrameworker != null){//置于中間上層Int32Animation animation1 = new Int32Animation{To = (int)CarouselZIndex.Center,Duration = TimeSpan.FromSeconds(_DelayAnimationTime),EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation1, vFrameworker);Storyboard.SetTargetProperty(animation1, new PropertyPath("(Panel.ZIndex)"));_Storyboard.Children.Add(animation1);//到中間DoubleAnimation animation2 = new DoubleAnimation{BeginTime = TimeSpan.FromSeconds(_DelayAnimationTime),To = _CenterDockLeft,Duration = TimeSpan.FromSeconds(_AnimationTime),EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation2, vFrameworker);Storyboard.SetTargetProperty(animation2, new PropertyPath("(Canvas.Left)"));_Storyboard.Children.Add(animation2);//縮放DoubleAnimation animation3 = new DoubleAnimation(){Duration = TimeSpan.FromSeconds(_AnimationTime),To = _ScaleRatioEx,EasingFunction = new ExponentialEase() { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation3, vFrameworker);Storyboard.SetTargetProperty(animation3, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"));_Storyboard.Children.Add(animation3);_mapCarouselLocationFramewokes[CarouselLoacation.Center] = i;}}}else if (i == vNext) //放右側(cè){if (_mapFrameworkes.ContainsKey(i)){var vFrameworker = _mapFrameworkes.GetValueOrDefault(i, null);if (vFrameworker != null){//置于右邊上層Int32Animation animation1 = new Int32Animation{To = (int)CarouselZIndex.Right,Duration = TimeSpan.FromSeconds(_DelayAnimationTime),EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation1, vFrameworker);Storyboard.SetTargetProperty(animation1, new PropertyPath("(Panel.ZIndex)"));_Storyboard.Children.Add(animation1);//到右邊DoubleAnimation animation2 = new DoubleAnimation{BeginTime = TimeSpan.FromSeconds(_DelayAnimationTime),To = _RightDockLeft,Duration = TimeSpan.FromSeconds(_AnimationTime),EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation2, vFrameworker);Storyboard.SetTargetProperty(animation2, new PropertyPath("(Canvas.Left)"));_Storyboard.Children.Add(animation2);//縮放DoubleAnimation animation3 = new DoubleAnimation(){Duration = TimeSpan.FromSeconds(_AnimationTime),To = _ScaleRatio,EasingFunction = new ExponentialEase() { EasingMode = EasingMode.EaseOut },};Storyboard.SetTarget(animation3, vFrameworker);Storyboard.SetTargetProperty(animation3, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"));_Storyboard.Children.Add(animation3);_mapCarouselLocationFramewokes[CarouselLoacation.Right] = i;}}}else_BufferLinkedList.AddLast(i);}_Storyboard?.Begin();return true;}bool Start(){if (!IsStartAinimation)return true;if (_IsAinimationStart)return true;_IsAinimationStart = true;_PlayTimer.Start();return true;}bool Stop(){if (_IsAinimationStart){_IsAinimationStart = false;_PlayTimer.Stop();}return true;}#endregionprivate void Storyboard_Completed(object sender, EventArgs e){_IsStoryboardWorking = false;}void PlayTimer_Elapsed(object sender, ElapsedEventArgs e){Application.Current.Dispatcher.BeginInvoke(new Action(() => PlayCarouselRightToLeft()));}void Border_PreviewMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e){if (e.ChangedButton != System.Windows.Input.MouseButton.Left)return;if (sender is FrameworkElement frameworkElement){if (int.TryParse(frameworkElement.Tag?.ToString(), out int nResult))PlayCarouselWithIndex(nResult);}}private void Border_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e){if (sender is FrameworkElement frameworkElement){if (int.TryParse(frameworkElement.Tag?.ToString(), out int nResult))PlayCarouselWithIndex(nResult);}}void MasterCarousel_SizeChanged(object sender, SizeChangedEventArgs e){Stop();if (CalculationShellReletiveProperty()){LoadCarousel();Start();}}private void MasterCarousel_Loaded(object sender, RoutedEventArgs e){if (_isLoaded)return;Stop();if (CalculationShellReletiveProperty()){LoadCarousel();Start();}_isLoaded = true;}} }二、Carousel.xaml?代碼如下?
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:controls="clr-namespace:WPFDevelopers.Controls"><ResourceDictionary.MergedDictionaries><ResourceDictionary Source="Basic/ControlBasic.xaml"/></ResourceDictionary.MergedDictionaries><Style TargetType="{x:Type controls:MasterCarousel}" BasedOn="{StaticResource ControlBasicStyle}"><Setter Property="Background" Value="Transparent"/><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type controls:MasterCarousel}"><Grid?Background="{TemplateBinding?Background}"?><Viewbox><Canvas x:Name="PART_ContentDock" Width="900" Height="400"/></Viewbox><StackPanel x:Name="PART_ButtonDock" Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center"Margin="0,210,0,0"/></Grid></ControlTemplate></Setter.Value></Setter> </Style></ResourceDictionary>三、CarouselExample.xaml 代碼如下?
<UserControl x:Class="WPFDevelopers.Samples.ExampleViews.CarouselExample"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WPFDevelopers.Samples.ExampleViews"xmlns:wpfdev="https://github.com/yanjinhuagood/WPFDevelopers"mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"><Grid><wpfdev:MasterCarousel IsStartAinimation="True"><wpfdev:MasterCarousel.Children><!--<Border Background="Red"/><Border Background="Blue"/><Border Background="Green"/><Border Background="Yellow"/><Border Background="Pink"/>--><Image Source="pack://application:,,,/WPFDevelopers.Samples;component/Images/Craouse/0.jpg"/><Image Source="pack://application:,,,/WPFDevelopers.Samples;component/Images/Craouse/1.jpg"/><Image Source="pack://application:,,,/WPFDevelopers.Samples;component/Images/Craouse/2.jpg"/><Image Source="pack://application:,,,/WPFDevelopers.Samples;component/Images/Craouse/3.jpg"/><Image Source="pack://application:,,,/WPFDevelopers.Samples;component/Images/Craouse/4.jpg"/></wpfdev:MasterCarousel.Children></wpfdev:MasterCarousel></Grid> </UserControl>源碼地址
github:https://github.com/yanjinhuagood/WPFDevelopers.git
gitee:https://gitee.com/yanjinhua/WPFDevelopers.git
WPF開發(fā)者QQ群:?340500857?
blogs:?https://www.cnblogs.com/yanjinhua
Github:https://github.com/yanjinhuagood
出處:https://www.cnblogs.com/yanjinhua
版權(quán):本作品采用「署名-非商業(yè)性使用-相同方式共享 4.0 國際」許可協(xié)議進行許可。
轉(zhuǎn)載請著名作者 出處 https://github.com/yanjinhuagood
總結(jié)
以上是生活随笔為你收集整理的WPF轮播图实现方式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何对 string 进行Base64编
- 下一篇: .NET 6 全新指标 System.D