WPF render image, scaletransfrom and translatertransform
<Window x:Class="WpfApp392.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:WpfApp392" mc:Ignorable="d" WindowState="Maximized" KeyDown="Window_KeyDown" MouseDown="img_MouseDown" MouseMove="img_MouseMove" MouseUp="img_MouseUp" Title="MainWindow" Height="450" Width="800"> <Grid> <Image x:Name="img" ClipToBounds="True" Source="{Binding ImgUrl,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" RenderOptions.BitmapScalingMode="HighQuality" MouseWheel="Image_MouseWheel"> <Image.RenderTransform> <TransformGroup> <ScaleTransform x:Name="scaler"/> <TranslateTransform x:Name="translater"/> </TransformGroup> </Image.RenderTransform> </Image> </Grid> </Window> using System; using System.Collections.Generic; 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.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace WpfApp392 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window, INotifyPropertyChanged { private List<string> imgsList { get; set; } private int imgsCount { get; set; } private int imgIndex { get; set; } private Point currentPt { get; set; } private bool isMoving = false; private string imgUrl { get; set; } public string ImgUrl { get { return imgUrl; } set { if(value!=imgUrl) { imgUrl = value; OnPropertyChanged(nameof(ImgUrl)); } } } public MainWindow() { InitializeComponent(); this.Loaded += MainWindow_Loaded; this.DataContext=this; } public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string propName) { var handler = PropertyChanged; if(handler!=null) { handler?.Invoke(this, new PropertyChangedEventArgs(propName)); } } private void MainWindow_Loaded(object sender, RoutedEventArgs e) { imgsList = Directory.GetFiles(@"../../Images")?.ToList(); if (imgsList != null && imgsList.Any()) { imgsCount = imgsList.Count(); imgIndex = 0; ImgUrl = imgsList[imgIndex]; } } private void Window_KeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.Up) { if (--imgIndex < 0) { imgIndex = imgsCount - 1; } } else if (e.Key==Key.Down) { if (++imgIndex>=imgsCount) { imgIndex = 0; } } this.Title = imgIndex.ToString(); ImgUrl = imgsList[imgIndex]; scaler.ScaleX = 1; scaler.ScaleY = 1; scaler.CenterX = 0; scaler.CenterY = 0; translater.X = 0; translater.Y = 0; } private void Image_MouseWheel(object sender, MouseWheelEventArgs e) { 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; translater.X = 0; translater.Y=0; } private void img_MouseDown(object sender, MouseButtonEventArgs e) { currentPt = e.GetPosition(this); } private void img_MouseMove(object sender, MouseEventArgs e) { isMoving = true; } private void img_MouseUp(object sender, MouseButtonEventArgs e) { if(e.ChangedButton==MouseButton.Left && e.ButtonState==MouseButtonState.Released && isMoving) { var pt = e.GetPosition(this); translater.X += (pt.X - currentPt.X); translater.Y += (pt.Y - currentPt.Y); isMoving = false; } } } }