diff --git a/Wpf_AiSportsMicrospace/Home.xaml b/Wpf_AiSportsMicrospace/Home.xaml
index 3532627..8e8d7ab 100644
--- a/Wpf_AiSportsMicrospace/Home.xaml
+++ b/Wpf_AiSportsMicrospace/Home.xaml
@@ -2,10 +2,8 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Wpf_AiSportsMicrospace.MyUserControl"
- Title="CoverFlow Demo" Height="400" Width="800">
+ Title="Home" Height="400" Width="800">
-
-
-
+
diff --git a/Wpf_AiSportsMicrospace/Home.xaml.cs b/Wpf_AiSportsMicrospace/Home.xaml.cs
index f56b0d9..b24d4d1 100644
--- a/Wpf_AiSportsMicrospace/Home.xaml.cs
+++ b/Wpf_AiSportsMicrospace/Home.xaml.cs
@@ -2,12 +2,14 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
+using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
-using System.Windows.Shapes;
-using System.IO;
+using System.Windows.Controls;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
using Wpf_AiSportsMicrospace.MyUserControl;
namespace Wpf_AiSportsMicrospace
@@ -21,20 +23,18 @@ namespace Wpf_AiSportsMicrospace
{
InitializeComponent();
- string projectRoot = System.IO.Path.Combine(AppContext.BaseDirectory, @"..\..\..");
- string albumPath = System.IO.Path.Combine(projectRoot, "Resources", "Img", "Album");
+ string projectRoot = Path.Combine(AppContext.BaseDirectory, @"..\..\..");
+ string albumPath = Path.Combine(projectRoot, "Resources", "Img", "Album");
- ObservableCollection images = new ObservableCollection()
- {
- new CoverImage( System.IO.Path.Combine(albumPath, "1.jpg"), System.IO.Path.Combine(projectRoot, "Resources/Img/Badge/1.jpg")),
- new CoverImage( System.IO.Path.Combine(albumPath, "2.jpg"), System.IO.Path.Combine(projectRoot, "Resources/Img/Badge/2.jpg")),
- new CoverImage( System.IO.Path.Combine(albumPath, "3.jpg"), System.IO.Path.Combine(projectRoot, "Resources/Img/Badge/3.jpg")),
- new CoverImage( System.IO.Path.Combine(albumPath, "4.jpg"), System.IO.Path.Combine(projectRoot, "Resources/Img/Badge/4.jpg")),
- new CoverImage( System.IO.Path.Combine(albumPath, "5.jpg"), System.IO.Path.Combine(projectRoot, "Resources/Img/Badge/5.jpg")),
- };
+ // 转换为 Uri
+ coverFlow.Images.Add(new Uri(Path.Combine(albumPath, "1.jpg")));
+ coverFlow.Images.Add(new Uri(Path.Combine(albumPath, "2.jpg")));
+ coverFlow.Images.Add(new Uri(Path.Combine(albumPath, "3.jpg")));
+ coverFlow.Images.Add(new Uri(Path.Combine(albumPath, "4.jpg")));
+ coverFlow.Images.Add(new Uri(Path.Combine(albumPath, "5.jpg")));
- // 设置 CoverFlow 图片s
- //coverFlow.SetImages(images, defaultSelectedIndex: 2);
+ // 默认选中第3张
+ coverFlow.SelectedIndex = 2;
}
}
-}
\ No newline at end of file
+}
diff --git a/Wpf_AiSportsMicrospace/MyUserControl/CoverFlowControl.xaml b/Wpf_AiSportsMicrospace/MyUserControl/CoverFlowControl.xaml
index 20a55b1..279a0d2 100644
--- a/Wpf_AiSportsMicrospace/MyUserControl/CoverFlowControl.xaml
+++ b/Wpf_AiSportsMicrospace/MyUserControl/CoverFlowControl.xaml
@@ -4,103 +4,29 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Wpf_AiSportsMicrospace.MyUserControl"
- mc:Ignorable="d" >
-
-
+ Height="300" Width="600">
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Wpf_AiSportsMicrospace/MyUserControl/CoverFlowControl.xaml.cs b/Wpf_AiSportsMicrospace/MyUserControl/CoverFlowControl.xaml.cs
index a66f488..c4e437f 100644
--- a/Wpf_AiSportsMicrospace/MyUserControl/CoverFlowControl.xaml.cs
+++ b/Wpf_AiSportsMicrospace/MyUserControl/CoverFlowControl.xaml.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
+using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
@@ -11,6 +12,7 @@ using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
+using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
@@ -22,77 +24,118 @@ namespace Wpf_AiSportsMicrospace.MyUserControl
///
public partial class CoverFlowControl : UserControl
{
- public ObservableCollection AllImages { get; set; } = new ObservableCollection();
- public ObservableCollection VisibleImages { get; set; } = new ObservableCollection();
+ public ObservableCollection Images { get; set; } = new ObservableCollection();
- private int selectedIndex = 0;
+ private int _selectedIndex = 0;
+ public int SelectedIndex
+ {
+ get => _selectedIndex;
+ set
+ {
+ if (value < 0 || value >= Images.Count) return;
+ _selectedIndex = value;
+ UpdateLayoutWithAnimation();
+ }
+ }
public CoverFlowControl()
{
InitializeComponent();
- VisibleImagesControl.ItemsSource = VisibleImages;
+ DataContext = this;
+ Loaded += (s, e) => UpdateLayoutWithAnimation(true);
}
- #region Public Methods
-
- public void SetImages(ObservableCollection images, int defaultSelectedIndex = 0)
- {
- AllImages = images;
- selectedIndex = defaultSelectedIndex;
- UpdateVisibleImages();
- }
-
- #endregion
-
private void Image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
- if (sender is Border border && border.DataContext is CoverImage img)
+ if (sender is Border border)
{
- int index = AllImages.IndexOf(img);
- if (index >= 0)
+ var container = ItemsHost.ItemContainerGenerator.ContainerFromItem(border.DataContext) as ContentPresenter;
+ if (container != null)
{
- selectedIndex = index;
- UpdateVisibleImages();
+ int index = ItemsHost.ItemContainerGenerator.IndexFromContainer(container);
+ SelectedIndex = index;
}
}
}
- private void UpdateVisibleImages()
+ private void UpdateLayoutWithAnimation(bool instant = false)
{
- VisibleImages.Clear();
- for (int offset = -1; offset <= 1; offset++)
+ double centerX = ActualWidth / 2;
+ double spacing = 180;
+ double sideScale = 0.8;
+ double centerScale = 1.2;
+
+ for (int i = 0; i < ItemsHost.Items.Count; i++)
{
- int idx = selectedIndex + offset;
- if (idx >= 0 && idx < AllImages.Count)
+ var container = ItemsHost.ItemContainerGenerator.ContainerFromIndex(i) as ContentPresenter;
+ if (container == null) continue;
+
+ var border = FindVisualChild(container);
+ if (border == null) continue;
+
+ var transformGroup = border.RenderTransform as TransformGroup;
+ var scale = transformGroup.Children[0] as ScaleTransform;
+ var translate = transformGroup.Children[1] as TranslateTransform;
+
+ double targetX;
+ double targetScale;
+ double targetOpacity;
+
+ if (i == SelectedIndex)
{
- var img = AllImages[idx];
- img.IsSelected = offset == 0;
- VisibleImages.Add(img);
+ targetX = centerX - 75;
+ targetScale = centerScale;
+ targetOpacity = 1.0;
+ }
+ else if (i == SelectedIndex - 1)
+ {
+ targetX = centerX - spacing - 75;
+ targetScale = sideScale;
+ targetOpacity = 1.0;
+ }
+ else if (i == SelectedIndex + 1)
+ {
+ targetX = centerX + spacing - 75;
+ targetScale = sideScale;
+ targetOpacity = 1.0;
+ }
+ else
+ {
+ targetX = centerX - 75;
+ targetScale = sideScale;
+ targetOpacity = 0.0;
+ }
+
+ if (instant)
+ {
+ translate.X = targetX;
+ scale.ScaleX = scale.ScaleY = targetScale;
+ border.Opacity = targetOpacity;
+ }
+ else
+ {
+ translate.BeginAnimation(TranslateTransform.XProperty,
+ new DoubleAnimation(targetX, TimeSpan.FromMilliseconds(400)) { EasingFunction = new QuadraticEase() });
+ scale.BeginAnimation(ScaleTransform.ScaleXProperty,
+ new DoubleAnimation(targetScale, TimeSpan.FromMilliseconds(400)) { EasingFunction = new QuadraticEase() });
+ scale.BeginAnimation(ScaleTransform.ScaleYProperty,
+ new DoubleAnimation(targetScale, TimeSpan.FromMilliseconds(400)) { EasingFunction = new QuadraticEase() });
+ border.BeginAnimation(Border.OpacityProperty,
+ new DoubleAnimation(targetOpacity, TimeSpan.FromMilliseconds(400)));
}
}
}
- }
- public class CoverImage : INotifyPropertyChanged
- {
- public string Path { get; set; }
- public string BadgePath { get; set; }
-
- private bool _isSelected;
- public bool IsSelected
+ private static T FindVisualChild(DependencyObject obj) where T : DependencyObject
{
- get => _isSelected;
- set { _isSelected = value; OnPropertyChanged(nameof(IsSelected)); }
+ for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
+ {
+ var child = VisualTreeHelper.GetChild(obj, i);
+ if (child is T target) return target;
+ var result = FindVisualChild(child);
+ if (result != null) return result;
+ }
+ return null;
}
-
- public CoverImage(string path, string badgePath = null)
- {
- Path = path;
- BadgePath = badgePath;
- }
-
- public event PropertyChangedEventHandler PropertyChanged;
- protected void OnPropertyChanged(string name) =>
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
diff --git a/Wpf_AiSportsMicrospace/Wpf_AiSportsMicrospace.csproj b/Wpf_AiSportsMicrospace/Wpf_AiSportsMicrospace.csproj
index 202d83a..b0f7d6a 100644
--- a/Wpf_AiSportsMicrospace/Wpf_AiSportsMicrospace.csproj
+++ b/Wpf_AiSportsMicrospace/Wpf_AiSportsMicrospace.csproj
@@ -32,6 +32,7 @@
+