WPF C# implement scaletransform and translatetransfrom programmatically

FredGrit發表於2024-08-02
private void InitRenderTransfrom()
{
    TransformGroup tg = new TransformGroup();
    ScaleTransform st = new ScaleTransform();
    if (!tg.Children.Contains(st))
    {
        tg.Children.Add(st);
        scaler = st;
    }
    TranslateTransform tt = new TranslateTransform();
    if (!tg.Children.Contains(tt))
    {
        tg.Children.Add(tt);
        translater = tt;
    }
    img.RenderTransform = tg;
}

//xaml
<Window x:Class="WpfApp3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp3"
        mc:Ignorable="d" WindowState="Maximized"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="250"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <ListView x:Name="lv" Grid.Column="0" ItemsSource="{Binding BooksCollection,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                  SelectedIndex="0"
                  SelectionChanged="ListView_SelectionChanged">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Image Source="{Binding Path=Content.ImgUrl,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ListBoxItem}}"
                           Width="250" Height="500" />
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <Grid Grid.Column="1" x:Name="imgGrid" Background="Transparent"
              MouseWheel="ImgGrid_MouseWheel" MouseDown="ImgGrid_MouseDown"
              MouseUp="ImgGrid_MouseUp" MouseMove="ImgGrid_MouseMove"
              ClipToBounds="True">
            <Image x:Name="img"
                   Source="{Binding Path=SelectedItem.ImgUrl,ElementName=lv}"/>
        </Grid>
    </Grid>
</Window>



//cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
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.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp3
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public MainWindow()
        {
            InitializeComponent();
            InitData();
            InitRenderTransfrom();
            this.DataContext = this;
        }

        private void InitData()
        {
            BooksCollection = new ObservableCollection<Book>();
            var imgsList = System.IO.Directory.GetFiles(@"../../Images")?.ToList();
            int len = imgsList.Count;
            for (int i = 0; i < 10000; i++)
            {
                BooksCollection.Add(new Book()
                {
                    Id = i + 1,
                    Name = $"Name_{i + 1}",
                    ImgUrl = imgsList[i % len]
                });
            }
        }

        private void InitRenderTransfrom()
        {
            TransformGroup tg = new TransformGroup();
            ScaleTransform st = new ScaleTransform();
            if (!tg.Children.Contains(st))
            {
                tg.Children.Add(st);
                scaler = st;
            }
            TranslateTransform tt = new TranslateTransform();
            if (!tg.Children.Contains(tt))
            {
                tg.Children.Add(tt);
                translater = tt;
            }
            img.RenderTransform = tg;
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        private ObservableCollection<Book> booksCollection;
        public ObservableCollection<Book> BooksCollection
        {
            get
            {
                return booksCollection;
            }
            set
            {
                if (value != booksCollection)
                {
                    booksCollection = value;
                    OnPropertyChanged(nameof(BooksCollection));
                }
            }
        }

        private ScaleTransform scaler { get; set; }
        private TranslateTransform translater { get; set; }
        private Point currentPt { get; set; }
        private bool isMoving = false;


        private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (scaler != null)
            {
                scaler.ScaleX = 1.0;
                scaler.ScaleY = 1.0;
                scaler.CenterX = 0;
                scaler.CenterY = 0;
            }

            if (translater != null)
            {
                translater.X = 0;
                translater.Y = 0;
            }
        }

        private void ImgGrid_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            if (scaler != null)
            {
                if (e.Delta > 0)
                {
                    scaler.ScaleX *= 1.2;
                    scaler.ScaleY *= 1.2;
                }
                else
                {
                    scaler.ScaleX /= 1.2;
                    scaler.ScaleY /= 1.2;
                }
                scaler.CenterX = e.GetPosition(img).X;
                scaler.CenterY = e.GetPosition(img).Y;

                if (scaler.ScaleX > 100 || scaler.ScaleX < 0.01)
                {
                    MessageBox.Show($"ScaleX:{scaler.ScaleX},ScaleY:{scaler.ScaleY},had exceeded more than 100X+,it will reset to 1");
                    scaler.ScaleX = 1.0;
                    scaler.ScaleY = 1.0;
                    scaler.CenterX = 0;
                    scaler.CenterY = 0;
                }
            }
        }

        private void ImgGrid_MouseDown(object sender, MouseButtonEventArgs e)
        {
            currentPt = e.GetPosition(imgGrid);
        }

        private void ImgGrid_MouseUp(object sender, MouseButtonEventArgs e)
        {
            if (e.ChangedButton == MouseButton.Left
                && e.ButtonState == MouseButtonState.Released
                && isMoving && translater != null)
            {
                var newPt = e.GetPosition(imgGrid);
                translater.X += (newPt.X - currentPt.X);
                translater.Y += (newPt.Y - currentPt.Y);
                isMoving = false;
            }
        }

        private void ImgGrid_MouseMove(object sender, MouseEventArgs e)
        {
            isMoving = true;
        }
    }

    public class Book
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string ImgUrl { get; set; }
    }
}

相關文章