WPF以鼠标当前位置进行缩放

<Window x:Class="ImageViewer.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:ImageViewer"
        mc:Ignorable="d"
        Title="MainWindow" Height="600" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="80"/>
        </Grid.RowDefinitions>
        <ScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden">
            <Grid Name="grid"  Background="White"
                     
                       PreviewMouseLeftButtonDown="img_MouseLeftButtonDown"
                       MouseLeftButtonUp="img_MouseLeftButtonUp"
                       MouseMove="img_MouseMove">

                <Image Stretch="None" Name="img"   PreviewMouseWheel="Img_MouseWheel"
                      
                         Source="1.png">
                    <Image.RenderTransform>
                        <TransformGroup  x:Name="group">
                            <ScaleTransform x:Name="mScaleTf" ScaleX="1.0" CenterX="0"/>
                            <TranslateTransform x:Name="mTranslateTf" X="0" Y="0"/>

                        </TransformGroup>
                    </Image.RenderTransform>
                    <Image.LayoutTransform>
                        <RotateTransform x:Name="rotateTransform" ></RotateTransform>
                    </Image.LayoutTransform>
                </Image>


            </Grid>
        </ScrollViewer>
   


        <StackPanel Grid.Row="1" Orientation="Horizontal">
            <Button x:Name="btnRotate" Click="btnRotate_Click" Margin="15" Width="100">旋转</Button>
            <Button x:Name="btnOrg" Click="BtnOrg_Click"  Margin="15" Width="100">1:1</Button>
            <Label Name="lbScale" Content="100%" VerticalAlignment="Center"></Label>
        </StackPanel>
    </Grid>

</Window>
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Input;

namespace ImageViewer
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        Point oldPt;
        public MainWindow()
        {
            InitializeComponent();
            this.Loaded += MainWindow_Loaded;
            grid.SizeChanged += Grid_SizeChanged;
        }

        private void Grid_SizeChanged(object sender, SizeChangedEventArgs e)
        {
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {

        }

        private void Img_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            if (e.Delta < 0)
            {
                if (mScaleTf.ScaleX <= 0.2)
                    return;
            }
            else if (e.Delta >  0)
            {
                if (mScaleTf.ScaleX >= 5)
                    return;
            }
            Point zoomCenter = e.GetPosition(img);
            //if (img.ActualHeight * mScaleTf.ScaleY < grid.ActualHeight && img.ActualWidth * mScaleTf.ScaleX < grid.ActualHeight)
            //{
            //    zoomCenter.X = img.ActualWidth / 2;
            //    zoomCenter.Y = img.ActualHeight / 2;
            //    img.HorizontalAlignment = HorizontalAlignment.Center;
            //    img.VerticalAlignment = VerticalAlignment.Center;

             
            //}
            double x = zoomCenter.X;
            double y = zoomCenter.Y;
            if (rotateTransform.Angle == 90)
            {
                zoomCenter.X = img.ActualHeight - zoomCenter.Y;
                zoomCenter.Y = x;
            }
            else if (rotateTransform.Angle == 180)
            {
                zoomCenter.X = img.ActualWidth - zoomCenter.X;
                zoomCenter.Y = img.ActualHeight - zoomCenter.Y;
            }
            else if (rotateTransform.Angle == 270)
            {
                zoomCenter.X = y;
                zoomCenter.Y = img.ActualWidth - x;
            }
            Point pt = img.RenderTransform.Inverse.Transform(zoomCenter);
            this.mTranslateTf.X = (zoomCenter.X - pt.X) * this.mScaleTf.ScaleX;
            this.mTranslateTf.Y = (zoomCenter.Y - pt.Y) * this.mScaleTf.ScaleY;
            this.mScaleTf.CenterX = zoomCenter.X;
            this.mScaleTf.CenterY = zoomCenter.Y;
            if (e.Delta > 0)
            {
                this.mScaleTf.ScaleX += 0.1;
                this.mScaleTf.ScaleY += 0.1;
            }
            else
            {
                this.mScaleTf.ScaleX -= 0.1;
                this.mScaleTf.ScaleY -= 0.1;
            }
            lbScale.Content = $"{Math.Round(mScaleTf.ScaleX * 100, 0)} %";
            //this.mScaleTf.ScaleX += e.Delta / 1500.0;
            //this.mScaleTf.ScaleY += e.Delta / 1500.0;


        }

        private void img_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            oldPt = e.GetPosition(grid);
        }

        private void img_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            oldPt = e.GetPosition(grid);
        }

        private void img_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                Point pt = e.GetPosition(grid);
                Point ptImg = e.GetPosition(img);
                Debug.WriteLine($"Grid:{pt.X}---{pt.Y}");
                Debug.WriteLine($"Img:{ptImg.X}---{ptImg.Y}");
                //if (pt.X > oldPt.X)//right drag
                //{
                //    if (e.GetPosition(img).X * mScaleTf.ScaleX > pt.X)
                //    {
                //        mTranslateTf.X += pt.X - oldPt.X;
                //    }
                //}
                //if (pt.Y > oldPt.Y)//down
                //{
                //    if (e.GetPosition(img).Y * mScaleTf.ScaleY > pt.Y)
                //    {
                //        mTranslateTf.Y += pt.Y - oldPt.Y;
                //    }
                //}
                //if (pt.X < oldPt.X)//left
                //{
                //    if ((img.ActualWidth - e.GetPosition(img).X) * mScaleTf.ScaleX > (grid.ActualWidth -pt.X))
                //        mTranslateTf.X += pt.X - oldPt.X;
                //}
                //if (pt.Y < oldPt.Y)//up
                //{
                //    if ((img.ActualHeight - e.GetPosition(img).Y) * mScaleTf.ScaleY > (grid.ActualHeight - pt.Y))
                //        mTranslateTf.Y += pt.Y - oldPt.Y;
                //}

                mTranslateTf.X += pt.X - oldPt.X;
                mTranslateTf.Y += pt.Y - oldPt.Y;
                oldPt = pt;
            }
        }

        private void btnRotate_Click(object sender, RoutedEventArgs e)
        {
            rotateTransform.Angle = (rotateTransform.Angle + 90) % 360;
        }

        private void BtnOrg_Click(object sender, RoutedEventArgs e)
        {
            rotateTransform.Angle = 0;
            mScaleTf.ScaleX = 1;
            mScaleTf.ScaleY = 1;
            mTranslateTf.X = 0;
            mTranslateTf.Y = 0;
        }
    }
}
原文地址:https://www.cnblogs.com/3xiaolonglong/p/14055667.html