// // This control is created by Ashley Davis and copyrighted under CPOL, and available as part of // a CodeProject article at // http://www.codeproject.com/KB/WPF/zoomandpancontrol.aspx // This code is based on the article dated: 29 Jun 2010 // using System; using System.Linq; using System.Text; using System.Collections.Generic; using System.Windows; using System.Windows.Media; using System.Windows.Controls; namespace SharpVectors.Runtime { /// /// This is an extension to the ZoomPanControl class that implements /// the IScrollInfo interface properties and functions. /// /// IScrollInfo is implemented to allow ZoomPanControl to be wrapped (in XAML) /// in a ScrollViewer. IScrollInfo allows the ScrollViewer and ZoomPanControl to /// communicate important information such as the horizontal and vertical scrollbar offsets. /// /// There is a good series of articles showing how to implement IScrollInfo starting here: /// http://blogs.msdn.com/bencon/archive/2006/01/05/509991.aspx /// /// public partial class ZoomPanControl { #region Public Properties /// /// Set to 'true' when the vertical scrollbar is enabled. /// public bool CanVerticallyScroll { get { return canVerticallyScroll; } set { canVerticallyScroll = value; } } /// /// Set to 'true' when the vertical scrollbar is enabled. /// public bool CanHorizontallyScroll { get { return canHorizontallyScroll; } set { canHorizontallyScroll = value; } } /// /// The width of the content (with 'ContentScale' applied). /// public double ExtentWidth { get { return unScaledExtent.Width * ContentScale; } } /// /// The height of the content (with 'ContentScale' applied). /// public double ExtentHeight { get { return unScaledExtent.Height * ContentScale; } } /// /// Get the width of the viewport onto the content. /// public double ViewportWidth { get { return viewport.Width; } } /// /// Get the height of the viewport onto the content. /// public double ViewportHeight { get { return viewport.Height; } } /// /// Reference to the ScrollViewer that is wrapped (in XAML) around the ZoomPanControl. /// Or set to null if there is no ScrollViewer. /// public ScrollViewer ScrollOwner { get { return scrollOwner; } set { scrollOwner = value; } } /// /// The offset of the horizontal scrollbar. /// public double HorizontalOffset { get { return ContentOffsetX * ContentScale; } } /// /// The offset of the vertical scrollbar. /// public double VerticalOffset { get { return ContentOffsetY * ContentScale; } } /// /// Called when the offset of the horizontal scrollbar has been set. /// public void SetHorizontalOffset(double offset) { if (disableScrollOffsetSync) { return; } try { disableScrollOffsetSync = true; ContentOffsetX = offset / ContentScale; } finally { disableScrollOffsetSync = false; } } #endregion #region Public Methods /// /// Called when the offset of the vertical scrollbar has been set. /// public void SetVerticalOffset(double offset) { if (disableScrollOffsetSync) { return; } try { disableScrollOffsetSync = true; ContentOffsetY = offset / ContentScale; } finally { disableScrollOffsetSync = false; } } /// /// Shift the content offset one line up. /// public void LineUp() { ContentOffsetY -= (ContentViewportHeight / 10); } /// /// Shift the content offset one line down. /// public void LineDown() { ContentOffsetY += (ContentViewportHeight / 10); } /// /// Shift the content offset one line left. /// public void LineLeft() { ContentOffsetX -= (ContentViewportWidth / 10); } /// /// Shift the content offset one line right. /// public void LineRight() { ContentOffsetX += (ContentViewportWidth / 10); } /// /// Shift the content offset one page up. /// public void PageUp() { ContentOffsetY -= ContentViewportHeight; } /// /// Shift the content offset one page down. /// public void PageDown() { ContentOffsetY += ContentViewportHeight; } /// /// Shift the content offset one page left. /// public void PageLeft() { ContentOffsetX -= ContentViewportWidth; } /// /// Shift the content offset one page right. /// public void PageRight() { ContentOffsetX += ContentViewportWidth; } /// /// Don't handle mouse wheel input from the ScrollViewer, the mouse wheel is /// used for zooming in and out, not for manipulating the scrollbars. /// public void MouseWheelDown() { if (IsMouseWheelScrollingEnabled) { LineDown(); } } /// /// Don't handle mouse wheel input from the ScrollViewer, the mouse wheel is /// used for zooming in and out, not for manipulating the scrollbars. /// public void MouseWheelLeft() { if (IsMouseWheelScrollingEnabled) { LineLeft(); } } /// /// Don't handle mouse wheel input from the ScrollViewer, the mouse wheel is /// used for zooming in and out, not for manipulating the scrollbars. /// public void MouseWheelRight() { if (IsMouseWheelScrollingEnabled) { LineRight(); } } /// /// Don't handle mouse wheel input from the ScrollViewer, the mouse wheel is /// used for zooming in and out, not for manipulating the scrollbars. /// public void MouseWheelUp() { if (IsMouseWheelScrollingEnabled) { LineUp(); } } /// /// Bring the specified rectangle to view. /// public Rect MakeVisible(Visual visual, Rect rectangle) { if (content.IsAncestorOf(visual)) { Rect transformedRect = visual.TransformToAncestor(content).TransformBounds(rectangle); if (!transformedRect.IntersectsWith(new Rect(ContentOffsetX, ContentOffsetY, ContentViewportWidth, ContentViewportHeight))) { AnimatedSnapTo(new Point(transformedRect.X + (transformedRect.Width / 2), transformedRect.Y + (transformedRect.Height / 2))); } } return rectangle; } #endregion } }