183 lines
6.1 KiB
C#
183 lines
6.1 KiB
C#
|
|
using _3DTools;
|
|||
|
|
using System;
|
|||
|
|
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.Controls;
|
|||
|
|
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.Media.Media3D;
|
|||
|
|
using System.Windows.Navigation;
|
|||
|
|
using System.Windows.Shapes;
|
|||
|
|
|
|||
|
|
namespace Wpf_AiSportsMicrospace.MyUserControl
|
|||
|
|
{
|
|||
|
|
public partial class CoverFlowControl : UserControl
|
|||
|
|
{
|
|||
|
|
public ObservableCollection<ImageItem> Images { get; set; } = new ObservableCollection<ImageItem>();
|
|||
|
|
|
|||
|
|
private int selectedIndex;
|
|||
|
|
public int SelectedIndex
|
|||
|
|
{
|
|||
|
|
get => selectedIndex;
|
|||
|
|
set
|
|||
|
|
{
|
|||
|
|
if (value < 0) value = 0;
|
|||
|
|
if (value >= Images.Count) value = Images.Count - 1;
|
|||
|
|
selectedIndex = value;
|
|||
|
|
UpdateSelectedItem();
|
|||
|
|
ScrollToSelected();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 设置默认显示图片
|
|||
|
|
public int DefaultIndex { get; set; } = 1;
|
|||
|
|
|
|||
|
|
private const double NormalWidth = 300;
|
|||
|
|
private const double NormalHeight = 500;
|
|||
|
|
private const double SelectedWidth = 360;
|
|||
|
|
private const double SelectedHeight = 600;
|
|||
|
|
|
|||
|
|
public CoverFlowControl()
|
|||
|
|
{
|
|||
|
|
InitializeComponent();
|
|||
|
|
LoadImages();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void LoadImages()
|
|||
|
|
{
|
|||
|
|
var paths = GetUserImages();
|
|||
|
|
for (int i = 0; i < paths.Count; i++)
|
|||
|
|
{
|
|||
|
|
Images.Add(new ImageItem { Path = paths[i], Index = i });
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
SelectedIndex = DefaultIndex; // 默认选中
|
|||
|
|
}
|
|||
|
|
private List<string> GetUserImages()
|
|||
|
|
{// 相对路径,基于可执行文件所在目录
|
|||
|
|
string relativePath = @"..\..\..\Resources\Img\Album";
|
|||
|
|
string path = System.IO.Path.GetFullPath(relativePath); // 转为绝对路径
|
|||
|
|
|
|||
|
|
|
|||
|
|
if (!Directory.Exists(path))
|
|||
|
|
return new List<string>();
|
|||
|
|
|
|||
|
|
var files = new DirectoryInfo(path).GetFiles("*.jpg", SearchOption.TopDirectoryOnly);
|
|||
|
|
return files.Select(f => f.FullName).ToList();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
private void UpdateSelectedItem()
|
|||
|
|
{
|
|||
|
|
for (int i = 0; i < Images.Count; i++)
|
|||
|
|
{
|
|||
|
|
if (i == SelectedIndex)
|
|||
|
|
{
|
|||
|
|
Images[i].IsSelected = true;
|
|||
|
|
Images[i].BorderBrush = Brushes.Red;
|
|||
|
|
Images[i].BorderThickness = 4;
|
|||
|
|
Images[i].ImageWidth = SelectedWidth;
|
|||
|
|
Images[i].ImageHeight = SelectedHeight;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
Images[i].IsSelected = false;
|
|||
|
|
Images[i].BorderBrush = Brushes.Transparent;
|
|||
|
|
Images[i].BorderThickness = 0;
|
|||
|
|
Images[i].ImageWidth = NormalWidth;
|
|||
|
|
Images[i].ImageHeight = NormalHeight;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void ScrollToSelected()
|
|||
|
|
{
|
|||
|
|
var container = ItemsPanelImages.ItemContainerGenerator.ContainerFromIndex(SelectedIndex) as FrameworkElement;
|
|||
|
|
if (container == null) return;
|
|||
|
|
|
|||
|
|
double offset = container.TransformToAncestor(Scroller).Transform(new Point(0, 0)).X;
|
|||
|
|
double scrollTarget = offset + container.ActualWidth / 2 - Scroller.ActualWidth / 2;
|
|||
|
|
|
|||
|
|
DoubleAnimation anim = new DoubleAnimation(scrollTarget, TimeSpan.FromMilliseconds(300));
|
|||
|
|
Scroller.BeginAnimation(ScrollViewerBehavior.HorizontalOffsetProperty, anim);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void BtnPrev_Click(object sender, RoutedEventArgs e) => SelectedIndex--;
|
|||
|
|
private void BtnNext_Click(object sender, RoutedEventArgs e) => SelectedIndex++;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public class ImageItem : INotifyPropertyChanged
|
|||
|
|
{
|
|||
|
|
public string Path { get; set; }
|
|||
|
|
public int Index { get; set; }
|
|||
|
|
|
|||
|
|
private bool isSelected;
|
|||
|
|
public bool IsSelected
|
|||
|
|
{
|
|||
|
|
get => isSelected;
|
|||
|
|
set { isSelected = value; OnPropertyChanged(nameof(IsSelected)); }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private Brush borderBrush;
|
|||
|
|
public Brush BorderBrush
|
|||
|
|
{
|
|||
|
|
get => borderBrush;
|
|||
|
|
set { borderBrush = value; OnPropertyChanged(nameof(BorderBrush)); }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private double borderThickness;
|
|||
|
|
public double BorderThickness
|
|||
|
|
{
|
|||
|
|
get => borderThickness;
|
|||
|
|
set { borderThickness = value; OnPropertyChanged(nameof(BorderThickness)); }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private double imageWidth;
|
|||
|
|
public double ImageWidth
|
|||
|
|
{
|
|||
|
|
get => imageWidth;
|
|||
|
|
set { imageWidth = value; OnPropertyChanged(nameof(ImageWidth)); }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private double imageHeight;
|
|||
|
|
public double ImageHeight
|
|||
|
|
{
|
|||
|
|
get => imageHeight;
|
|||
|
|
set { imageHeight = value; OnPropertyChanged(nameof(ImageHeight)); }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public event PropertyChangedEventHandler PropertyChanged;
|
|||
|
|
private void OnPropertyChanged(string prop) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));
|
|||
|
|
}
|
|||
|
|
public class ScrollViewerBehavior
|
|||
|
|
{
|
|||
|
|
public static readonly DependencyProperty HorizontalOffsetProperty =
|
|||
|
|
DependencyProperty.RegisterAttached("HorizontalOffset", typeof(double), typeof(ScrollViewerBehavior),
|
|||
|
|
new PropertyMetadata(0.0, OnHorizontalOffsetChanged));
|
|||
|
|
|
|||
|
|
private static void OnHorizontalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|||
|
|
{
|
|||
|
|
if (d is ScrollViewer scroll)
|
|||
|
|
{
|
|||
|
|
scroll.ScrollToHorizontalOffset((double)e.NewValue);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public static void SetHorizontalOffset(DependencyObject element, double value)
|
|||
|
|
=> element.SetValue(HorizontalOffsetProperty, value);
|
|||
|
|
|
|||
|
|
public static double GetHorizontalOffset(DependencyObject element)
|
|||
|
|
=> (double)element.GetValue(HorizontalOffsetProperty);
|
|||
|
|
}
|
|||
|
|
}
|