Загрузка данных
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
namespace DogGalleryWPF
{
public partial class MainWindow : Window
{
private class DogBreed
{
public string Name { get; set; }
public string ImagePath { get; set; }
}
private List<DogBreed> gallery = new List<DogBreed>();
private int currentIndex = 0;
// Переменные для отслеживания свайпа
private bool isDragging = false;
private Point startPoint;
public MainWindow()
{
InitializeComponent();
LoadGallery();
UpdateCard();
}
private void LoadGallery()
{
// Укажите относительные пути к вашим добавленным ресурсам
gallery.Add(new DogBreed { Name = "Сибирский хаски", ImagePath = "Images/husky.jpg" });
gallery.Add(new DogBreed { Name = "Мопс", ImagePath = "Images/pug.jpg" });
gallery.Add(new DogBreed { Name = "Вельш-корги", ImagePath = "Images/corgi.jpg" });
}
private void UpdateCard()
{
if (gallery.Count == 0) return;
TxtBreedName.Text = gallery[currentIndex].Name;
// Загрузка ресурса изображения
Uri uri = new Uri($"pack://application:,,,/{gallery[currentIndex].ImagePath}");
ImgDog.Source = new BitmapImage(uri);
}
// 1. Нажали левую кнопку мыши
private void OnSwipeStart(object sender, MouseButtonEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
isDragging = true;
startPoint = e.GetPosition(this);
// Захватываем ввод мыши, чтобы свайп не срывался при выходе за пределы карточки
((UIElement)sender).CaptureMouse();
}
}
// 2. Ведем курсор с зажатой кнопкой (картинка следует за мышью)
private void OnSwipeMove(object sender, MouseEventArgs e)
{
if (!isDragging) return;
Point currentPoint = e.GetPosition(this);
double deltaX = currentPoint.X - startPoint.X;
// Сдвигаем текущую картинку горизонтально
ImgTransform.X = deltaX;
}
// 3. Отпустили кнопку мыши
private void OnSwipeEnd(object sender, MouseButtonEventArgs e)
{
if (!isDragging) return;
isDragging = false;
((UIElement)sender).ReleaseMouseCapture();
Point endPoint = e.GetPosition(this);
double deltaX = endPoint.X - startPoint.X;
double threshold = 70; // Минимальная дистанция свайпа в пикселях
if (deltaX < -threshold)
{
// Свайп влево: смахиваем текущую карточку и показываем следующую
SwipeTo(next: true);
}
else if (deltaX > threshold)
{
// Свайп вправо: смахиваем текущую карточку и показываем предыдущую
SwipeTo(next: false);
}
else
{
// Недотянули — плавно возвращаем картинку на центр
AnimateReturn();
}
}
// Плавный вылет карточки и появление следующей
private void SwipeTo(bool next)
{
double exitX = next ? -Width : Width;
DoubleAnimation exitAnimation = new DoubleAnimation
{
To = exitX,
Duration = TimeSpan.FromMilliseconds(150)
};
exitAnimation.Completed += (s, e) =>
{
// Переключаем индекс
if (next)
{
currentIndex = (currentIndex + 1) % gallery.Count;
}
else
{
currentIndex = (currentIndex - 1 + gallery.Count) % gallery.Count;
}
UpdateCard();
// Появление с противоположной стороны
ImgTransform.X = next ? Width : -Width;
DoubleAnimation enterAnimation = new DoubleAnimation
{
To = 0,
Duration = TimeSpan.FromMilliseconds(200),
EasingFunction = new QuadraticEase { EasingMode = EasingMode.EaseOut }
};
ImgTransform.BeginAnimation(TranslateTransform.XProperty, enterAnimation);
};
ImgTransform.BeginAnimation(TranslateTransform.XProperty, exitAnimation);
}
// Возврат на центр, если жест был слишком коротким
private void AnimateReturn()
{
DoubleAnimation returnAnimation = new DoubleAnimation
{
To = 0,
Duration = TimeSpan.FromMilliseconds(150),
EasingFunction = new QuadraticEase { EasingMode = EasingMode.EaseOut }
};
ImgTransform.BeginAnimation(TranslateTransform.XProperty, returnAnimation);
}
}
}