WPF - Zooming in on an image inside a scroll viewer, and having the scrollbars adjust accordingly WPF - Zooming in on an image inside a scroll viewer, and having the scrollbars adjust accordingly wpf wpf

WPF - Zooming in on an image inside a scroll viewer, and having the scrollbars adjust accordingly


You should be using LayoutTransform instead of RenderTransform on your Image.

RenderTransform happens after layout completes and is visual only. LayoutTransform is done before the layout pass and so can notify the ScrollViewer of the new size.

See here for more info: http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.layouttransform.aspx


For pure scrolling I'd rather use a ScaleTransform, it should adjust the scrollbars accordingly.You can try below code if it fixes your issue.

private double _zoomValue = 1.0;private void UIElement_OnMouseWheel(object sender, MouseWheelEventArgs e){  if (e.Delta > 0)  {    _zoomValue += 0.1;  }  else  {    _zoomValue -= 0.1;  }  ScaleTransform scale = new ScaleTransform(_zoomValue, _zoomValue);  MyImage.LayoutTransform = scale;  e.Handled = true;}


Let's assume you have a Canvas_Main inside a ViewBox_CanvasMain, which in turn inside a ScrollViewer_CanvasMain. You want to zoom in by turning the mouse wheel, and the ScrollViewer will adjust the offset automatically so the feature (pointed by the mouse in the Canvas_Main) stays during the zoom in/out. It is complex but here is the code called by the mouse wheel eventhandler:

    private void MouseWheelZoom(MouseWheelEventArgs e)    {        if(Canvas_Main.IsMouseOver)        {            Point mouseAtImage = e.GetPosition(Canvas_Main); // ScrollViewer_CanvasMain.TranslatePoint(middleOfScrollViewer, Canvas_Main);            Point mouseAtScrollViewer = e.GetPosition(ScrollViewer_CanvasMain);            ScaleTransform st = ViewBox_CanvasMain.LayoutTransform as ScaleTransform;            if (st == null)            {                st = new ScaleTransform();                ViewBox_CanvasMain.LayoutTransform = st;            }            if (e.Delta > 0)            {                st.ScaleX = st.ScaleY = st.ScaleX * 1.25;                if (st.ScaleX > 64) st.ScaleX = st.ScaleY = 64;            }            else            {                st.ScaleX = st.ScaleY = st.ScaleX / 1.25;                if (st.ScaleX < 1) st.ScaleX = st.ScaleY = 1;            }            #region [this step is critical for offset]            ScrollViewer_CanvasMain.ScrollToHorizontalOffset(0);            ScrollViewer_CanvasMain.ScrollToVerticalOffset(0);            this.UpdateLayout();            #endregion            Vector offset = Canvas_Main.TranslatePoint(mouseAtImage, ScrollViewer_CanvasMain) - mouseAtScrollViewer; // (Vector)middleOfScrollViewer;            ScrollViewer_CanvasMain.ScrollToHorizontalOffset(offset.X);            ScrollViewer_CanvasMain.ScrollToVerticalOffset(offset.Y);            this.UpdateLayout();            e.Handled = true;        }    }