Advertisement
Guest User

ScrollViewerZoomPanHelper

a guest
Jan 18th, 2012
653
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.74 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Windows.Controls;
  6. using System.Windows.Input;
  7. using System.Windows;
  8. using System.Windows.Media;
  9.  
  10. namespace WpfCore.Helpers {
  11.     public class ScrollViewerZoomPanHelper {//adapted from http://www.codeproject.com/KB/docview/WpfZoomAndDragPanel.aspx
  12.         Point? lastCenterPositionOnTarget;
  13.         Point? lastMousePositionOnTarget;
  14.         Point? lastDragPoint;
  15.  
  16.         public event EventHandler ZoomChanged;
  17.  
  18.         protected void Call_ZoomChanged() {
  19.             if (ZoomChanged != null) {
  20.                 ZoomChanged(null, new EventArgs());
  21.             }
  22.         }
  23.  
  24.         private ScrollViewer m_ScrollViewer;
  25.         public ScrollViewer ScrollViewer {
  26.             get {
  27.                 return m_ScrollViewer;
  28.             }
  29.             set {
  30.                 m_ScrollViewer = value;
  31.                 SubscribeEvents();
  32.             }
  33.         }
  34.  
  35.         private FrameworkElement m_ScaledElement;
  36.         public FrameworkElement ScaledElement {
  37.             get {
  38.                 return m_ScaledElement;
  39.             }
  40.             set {
  41.                 m_ScaledElement = value;
  42.  
  43.             }
  44.         }
  45.  
  46.         private double m_MinZoom;
  47.         public double MinZoom {
  48.             get {
  49.                 return m_MinZoom;
  50.             }
  51.             set {
  52.                 m_MinZoom = value;
  53.             }
  54.         }
  55.  
  56.         private double m_MaxZoom;
  57.         public double MaxZoom {
  58.             get {
  59.                 return m_MaxZoom;
  60.             }
  61.             set {
  62.                 m_MaxZoom = value;
  63.             }
  64.         }
  65.  
  66.         private double m_Zoom;
  67.         public double Zoom {
  68.             get {
  69.                 return m_Zoom;
  70.             }
  71.             set {
  72.                 m_Zoom = Math.Min(m_MaxZoom, Math.Max(m_MinZoom, value));
  73.                 UpdateZoom();
  74.             }
  75.         }
  76.  
  77.         private double m_ChangePercent = 0.1;
  78.         public double ChangePercent {
  79.             get {
  80.                 return m_ChangePercent;
  81.             }
  82.             set {
  83.                 m_ChangePercent = value;
  84.             }
  85.         }
  86.  
  87.         private void UpdateZoom() {
  88.             m_ScaledElement.LayoutTransform.SetValue(ScaleTransform.ScaleYProperty, m_Zoom);
  89.             m_ScaledElement.LayoutTransform.SetValue(ScaleTransform.ScaleXProperty, m_Zoom);
  90.  
  91.             var centerOfViewport = new Point(m_ScrollViewer.ViewportWidth / 2, m_ScrollViewer.ViewportHeight / 2);
  92.             lastCenterPositionOnTarget = m_ScrollViewer.TranslatePoint(centerOfViewport, m_ScaledElement);
  93.         }
  94.  
  95.         private void SubscribeEvents() {
  96.             if (m_ScrollViewer == null) return;
  97.             m_ScrollViewer.ScrollChanged += OnScrollViewerScrollChanged;
  98.             m_ScrollViewer.MouseLeftButtonUp += OnMouseLeftButtonUp;
  99.             m_ScrollViewer.PreviewMouseLeftButtonUp += OnMouseLeftButtonUp;
  100.             m_ScrollViewer.PreviewMouseWheel += OnPreviewMouseWheel;
  101.  
  102.             m_ScrollViewer.PreviewMouseLeftButtonDown += OnMouseLeftButtonDown;
  103.             m_ScrollViewer.MouseMove += OnMouseMove;
  104.         }
  105.  
  106.         void OnMouseMove(object sender, MouseEventArgs e) {
  107.             if (lastDragPoint.HasValue) {
  108.                 Point posNow = e.GetPosition(m_ScrollViewer);
  109.  
  110.                 double dX = posNow.X - lastDragPoint.Value.X;
  111.                 double dY = posNow.Y - lastDragPoint.Value.Y;
  112.  
  113.                 lastDragPoint = posNow;
  114.  
  115.                 m_ScrollViewer.ScrollToHorizontalOffset(m_ScrollViewer.HorizontalOffset - dX);
  116.                 m_ScrollViewer.ScrollToVerticalOffset(m_ScrollViewer.VerticalOffset - dY);
  117.             }
  118.         }
  119.  
  120.         void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
  121.             var mousePos = e.GetPosition(m_ScrollViewer);
  122.             if (mousePos.X <= m_ScrollViewer.ViewportWidth && mousePos.Y < m_ScrollViewer.ViewportHeight) //make sure we still can use the scrollbars
  123.             {
  124.                 m_ScrollViewer.Cursor = Cursors.SizeAll;
  125.                 lastDragPoint = mousePos;
  126.                 Mouse.Capture(m_ScrollViewer);
  127.             }
  128.         }
  129.  
  130.         void OnPreviewMouseWheel(object sender, MouseWheelEventArgs e) {
  131.             lastMousePositionOnTarget = Mouse.GetPosition(m_ScaledElement);
  132.  
  133.             if (e.Delta > 0) {
  134.                 Zoom *= (1 + m_ChangePercent);
  135.                 Call_ZoomChanged();
  136.             }
  137.             if (e.Delta < 0) {
  138.                 Zoom /= (1 + m_ChangePercent);
  139.                 Call_ZoomChanged();
  140.             }
  141.  
  142.             e.Handled = true;
  143.         }
  144.  
  145.         void OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e) {
  146.             m_ScrollViewer.Cursor = Cursors.Arrow;
  147.             m_ScrollViewer.ReleaseMouseCapture();
  148.             lastDragPoint = null;
  149.         }
  150.  
  151.         void OnScrollViewerScrollChanged(object sender, ScrollChangedEventArgs e) {
  152.             if (e.ExtentHeightChange != 0 || e.ExtentWidthChange != 0) {
  153.                 Point? targetBefore = null;
  154.                 Point? targetNow = null;
  155.  
  156.                 if (!lastMousePositionOnTarget.HasValue) {
  157.                     if (lastCenterPositionOnTarget.HasValue) {
  158.                         var centerOfViewport = new Point(m_ScrollViewer.ViewportWidth / 2, m_ScrollViewer.ViewportHeight / 2);
  159.                         Point centerOfTargetNow = m_ScrollViewer.TranslatePoint(centerOfViewport, m_ScaledElement);
  160.  
  161.                         targetBefore = lastCenterPositionOnTarget;
  162.                         targetNow = centerOfTargetNow;
  163.                     }
  164.                 } else {
  165.                     targetBefore = lastMousePositionOnTarget;
  166.                     targetNow = Mouse.GetPosition(m_ScaledElement);
  167.  
  168.                     lastMousePositionOnTarget = null;
  169.                 }
  170.  
  171.                 if (targetBefore.HasValue) {
  172.                     double dXInTargetPixels = targetNow.Value.X - targetBefore.Value.X;
  173.                     double dYInTargetPixels = targetNow.Value.Y - targetBefore.Value.Y;
  174.  
  175.                     double multiplicatorX = e.ExtentWidth / m_ScaledElement.Width;
  176.                     double multiplicatorY = e.ExtentHeight / m_ScaledElement.Height;
  177.  
  178.                     double newOffsetX = m_ScrollViewer.HorizontalOffset - dXInTargetPixels * multiplicatorX;
  179.                     double newOffsetY = m_ScrollViewer.VerticalOffset - dYInTargetPixels * multiplicatorY;
  180.  
  181.                     if (double.IsNaN(newOffsetX) || double.IsNaN(newOffsetY)) {
  182.                         return;
  183.                     }
  184.  
  185.                     m_ScrollViewer.ScrollToHorizontalOffset(newOffsetX);
  186.                     m_ScrollViewer.ScrollToVerticalOffset(newOffsetY);
  187.                 }
  188.             }
  189.         }
  190.     }
  191. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement