How to implement zoom In zoom out on mouse pointer in WPF C#

tink 0 Reputation points
2023-10-14T07:41:50.5833333+00:00
I am facing problem to implement  the zoom in zoom out feature base on mouse pointer,


In my xaml i am having bellow code.
<ItemsControl x:Name="DiagramDesignerCanvasContainer">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <s:DiagramDesignerCanvas x:Name="diagramDesigner">
            </s:DiagramDesignerCanvas>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

please help me out to implement this feature.
i am using WPF C#.
Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,686 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,388 questions
{count} votes

2 answers

Sort by: Most helpful
  1. gekka 7,091 Reputation points MVP
    2023-10-14T12:13:40.9533333+00:00
    <ItemsControl x:Name="DiagramDesignerCanvasContainer"
                    Width="300" Height="300" ClipToBounds="true"
                    Background="Yellow" >
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas Width="200" Height="200" HorizontalAlignment="Left" VerticalAlignment="Top"
                        Loaded="Canvas_Loaded" >
                    <Canvas.Background>
                        <LinearGradientBrush>
                            <GradientStop Color="LightBlue" Offset="0" />
                            <GradientStop Color="Green" Offset="1" />
                        </LinearGradientBrush>
                    </Canvas.Background>
                </Canvas>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    
        <TextBlock Text="Test" Canvas.Left="50" Canvas.Top="50" Foreground="Red" FontWeight="Bold" FontSize="50"/>
    </ItemsControl>
    
    namespace WpfApp1
    {
        using System;
        using System.Linq;
        using System.Windows;
        using System.Windows.Controls;
        using System.Windows.Media;
    
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void Canvas_Loaded(object sender, RoutedEventArgs e)
            {
                tool = new MouseZoomMoveTool((Canvas)sender);
            }
    
            MouseZoomMoveTool tool;
        }
    
        class MouseZoomMoveTool
        {
            private UIElement element;
            private Point dragStartPoint;
            private System.Windows.Media.Matrix dragMatrix;
    
            public MouseZoomMoveTool(UIElement element)
            {
                this.element = element;
    
                DependencyObject d = element;
                while (d != null)
                {
                    d = VisualTreeHelper.GetParent(d);
                    if (d is Control control)
                    {
                        if (control.Background is null)
                        {
                            control.Background = Brushes.Transparent;
                        }
    
                        control.MouseWheel += Control_MouseWheel;
                        control.MouseLeftButtonDown += Control_MouseLeftButtonDown;
                        break;
                    }
                }
            }
    
            private void Control_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
            {
                var c = (Control)sender;
                if (c.CaptureMouse())
                {
                    c.MouseMove += Control_MouseMove;
                    c.MouseLeftButtonUp += Control_MouseLeftButtonUp;
    
                    this.dragStartPoint = e.GetPosition(c);
                    this.dragMatrix = GetMatrixTransform().Matrix;
                    e.Handled = true;
                }
            }
    
    
            private void Control_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
            {
                var control = (Control)sender;
                MatrixTransform mt = GetMatrixTransform();
    
                var p2 = e.GetPosition(control);
    
                var matrix = dragMatrix;
    
                var x = (p2.X - dragStartPoint.X) * matrix.M11;
                var y = (p2.Y - dragStartPoint.Y) * matrix.M11;
    
                matrix.Translate(x, y);
    
                mt.Matrix = matrix;
    
                e.Handled = true;
            }
    
            private void Control_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
            {
                var control = (Control)sender;
                control.ReleaseMouseCapture();
                control.MouseMove -= Control_MouseMove;
                control.MouseUp -= Control_MouseLeftButtonUp;
    
                e.Handled = true;
            }
    
            private void Control_MouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs me)
            {
                var control = (Control)sender;
                if (control.IsMouseCaptured)
                {
                    return;
                }
    
    
                MatrixTransform mt = GetMatrixTransform();
    
                var p = me.GetPosition(this.element);
                var matrix = mt.Matrix;
    
                double scaleCurrent = matrix.M11;
                double scaleDelta = (me.Delta > 0) ? 0.95 : 1.05;
    
                var p2 = matrix.Transform(new Point(0, 0));
                var centerX = scaleCurrent * p.X + p2.X;
                var centerY = scaleCurrent * p.Y + p2.Y;
    
                matrix.ScaleAt(scaleDelta, scaleDelta, centerX, centerY);
                mt.Matrix = matrix;
    
                me.Handled = true;
            }
    
    
            private MatrixTransform GetMatrixTransform()
            {
                if (!(element.RenderTransform is MatrixTransform mt) || mt.IsFrozen)
                {
                    mt = new MatrixTransform();
                    element.RenderTransform = mt;
                }
                return mt;
            }
    
        }
    }
    
    
    0 comments No comments

  2. Hui Liu-MSFT 41,261 Reputation points Microsoft Vendor
    2023-10-17T11:38:29.6366667+00:00

    Hi,@tink. Welcome to Microsoft Q&A. To implement zoom in and zoom out functionality based on the mouse pointer in a WPF application, you can use the ScaleTransform property in combination with the RenderTransform property of the UI element you want to zoom. Here's an example that demonstrates how you can achieve this in your WPF application:

     <ItemsControl x:Name="DiagramDesignerCanvasContainer" MouseWheel="DiagramDesignerCanvasContainer_MouseWheel">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Canvas x:Name="diagramDesigner">
                            <Canvas.Background>
                                <LinearGradientBrush>
                                    <GradientStop Color="LightBlue" Offset="0" />
                                    <GradientStop Color="Green" Offset="1" />
                                </LinearGradientBrush>
                            </Canvas.Background>
                        </Canvas>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <TextBlock Text="Test" Canvas.Left="50" Canvas.Top="50" Foreground="Red" FontWeight="Bold" FontSize="50"/>
            </ItemsControl>
      
    

    Codebehind:

     public partial class MainWindow : Window
        {
            private double _scaleValue = 1.0;
    
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void DiagramDesignerCanvasContainer_MouseWheel(object sender, MouseWheelEventArgs e)
            {
                // Determine the direction of the zoom (in or out)
                bool zoomIn = e.Delta > 0;
    
                // Set the scale value based on the direction of the zoom
                _scaleValue += zoomIn ? 0.1 : -0.1;
    
                // Set the maximum and minimum scale values
                _scaleValue = _scaleValue < 0.1 ? 0.1 : _scaleValue;
                _scaleValue = _scaleValue > 10.0 ? 10.0 : _scaleValue;
    
                // Apply the scale transformation to the ItemsControl
                ScaleTransform scaleTransform = new ScaleTransform(_scaleValue, _scaleValue);
                DiagramDesignerCanvasContainer.LayoutTransform = scaleTransform;
            }
        }
    
    
    

    The result:

    9

    This code allows you to zoom in and out of the ItemsControl (in this case, a Canvas) by using the mouse wheel. Adjust the logic as needed to apply the zoom functionality to the specific UI element you want to zoom in your application.


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments