WPF ZoomIn ZoomOut Pan ListBox Image
<ListBox x:Name="lbx" Grid.Row="1" Grid.Column="0" ItemsSource="{Binding ImgsList,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" SelectionChanged="lbx_SelectionChanged" SelectedIndex="{Binding ImgIdx,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" > <ListBox.ItemTemplate> <DataTemplate> <Image Source="{Binding Content,RelativeSource={RelativeSource AncestorType=ListBoxItem}}" Width="200" Height="500"/> </DataTemplate> </ListBox.ItemTemplate> </ListBox> <Image Grid.Row="1" Grid.Column="1" x:Name="img" ClipToBounds="True" Source="{Binding SelectedItem,ElementName=lbx}"> <Image.RenderTransform> <TransformGroup> <ScaleTransform x:Name="scaler"/> <TranslateTransform x:Name="translater"/> </TransformGroup> </Image.RenderTransform> </Image>
//xaml <Window x:Class="WpfApp226.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:WpfApp226" mc:Ignorable="d" WindowState="Maximized" MouseWheel="Window_MouseWheel" MouseDown="Window_MouseDown" MouseUp="Window_MouseUp" MouseMove="Window_MouseMove" Title="MainWindow" Height="450" Width="800"> <Window.Resources> <Style TargetType="Button"> <Setter Property="Width" Value="100"/> </Style> </Window.Resources> <Grid> <Grid.RowDefinitions> <RowDefinition Height="50"/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="200"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <ToolBar Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2"> <Button Content="ZoomIn +" x:Name="ZoomInBtn" Click="ZoomInBtn_Click" Width="100"/> <Button Content="ZoomOut -" x:Name="ZoomOutBtn" Click="ZoomOutBtn_Click" Width="100"/> <Button Content="Pan" x:Name="panBtn" Click="panBtn_Click"/> </ToolBar> <ListBox x:Name="lbx" Grid.Row="1" Grid.Column="0" ItemsSource="{Binding ImgsList,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" SelectionChanged="lbx_SelectionChanged" SelectedIndex="{Binding ImgIdx,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" > <ListBox.ItemTemplate> <DataTemplate> <Image Source="{Binding Content,RelativeSource={RelativeSource AncestorType=ListBoxItem}}" Width="200" Height="500"/> </DataTemplate> </ListBox.ItemTemplate> </ListBox> <Image Grid.Row="1" Grid.Column="1" x:Name="img" ClipToBounds="True" Source="{Binding SelectedItem,ElementName=lbx}"> <Image.RenderTransform> <TransformGroup> <ScaleTransform x:Name="scaler"/> <TranslateTransform x:Name="translater"/> </TransformGroup> </Image.RenderTransform> </Image> </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; using System.IO; using System.Windows.Interop; namespace WpfApp226 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window,INotifyPropertyChanged { private ObservableCollection<string> imgsList; public ObservableCollection<string> ImgsList { get { return imgsList; } set { if(value!=imgsList) { imgsList = value; OnPropertyChanged(nameof(ImgsList)); } } } private bool IsPanOpen = false; private int imgIdx = 0; public int ImgIdx { get { return imgIdx; } set { if(value!=imgIdx) { imgIdx = value; OnPropertyChanged(nameof(ImgIdx)); } } } private int ImgsCount = 0; public MainWindow() { InitializeComponent(); this.DataContext = this; this.Loaded += MainWindow_Loaded; ImgsList = new ObservableCollection<string>(Directory.GetFiles(@"../../Images")); ImgsCount = ImgsList.Count; RenderOptions.ProcessRenderMode = RenderMode.SoftwareOnly; System.Timers.Timer tmr = new System.Timers.Timer(); tmr.Interval = 100; tmr.Elapsed += Tmr_Elapsed; tmr.Enabled = true; } private void Tmr_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { if(++ImgIdx>=ImgsCount) { ImgIdx = 0; } } private void MainWindow_Loaded(object sender, RoutedEventArgs e) { currentPt=new Point(this.ActualWidth/2, this.ActualHeight/2); } private void cvs_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(this).X; scaler.CenterY = e.GetPosition(this).Y; } private void Window_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; } Point currentPt { get; set; } bool isMoving = false; public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string propName) { var handler = PropertyChanged; if(handler!=null) { handler?.Invoke(this, new PropertyChangedEventArgs(propName)); } } private void Window_MouseDown(object sender, MouseButtonEventArgs e) { currentPt= e.GetPosition(img); } private void Window_MouseUp(object sender, MouseButtonEventArgs e) { if(e.ButtonState == MouseButtonState.Released && e.ChangedButton==MouseButton.Left && isMoving) { Point newPt= e.GetPosition(img); translater.X += scaler.ScaleX * (newPt.X - currentPt.X); translater.Y += scaler.ScaleY * (newPt.Y - currentPt.Y); isMoving = false; IsPanOpen = false; } } private void Window_MouseMove(object sender, MouseEventArgs e) { if (e.LeftButton==MouseButtonState.Pressed) { isMoving = true; } } private void ZoomInBtn_Click(object sender, RoutedEventArgs e) { scaler.ScaleX *= 1.2; scaler.ScaleY *= 1.2; scaler.CenterX = currentPt.X; scaler.CenterY = currentPt.Y; } private void ZoomOutBtn_Click(object sender, RoutedEventArgs e) { scaler.ScaleX /= 1.2; scaler.ScaleY /= 1.2; scaler.CenterX = currentPt.X; scaler.CenterY = currentPt.Y; } private void panBtn_Click(object sender, RoutedEventArgs e) { IsPanOpen = true; } private void lbx_SelectionChanged(object sender, SelectionChangedEventArgs e) { scaler.ScaleX = 1.0; scaler.ScaleY = 1.0; scaler.CenterX = 0; scaler.CenterY = 0; translater.X = 0; translater.Y=0; } } }