private void ApplyZoomToChildren(ZoomEventArgs e) { foreach (UIElement cur in this.Children) { cur.RenderTransform = e.NewScale; Canvas.SetLeft(cur, e.ContentOffset.X); Canvas.SetTop(cur, e.ContentOffset.Y); } }
protected override void OnMouseWheel(MouseWheelEventArgs e) { e.Handled = true; //Calculate new scaling factor if ((_wheelOffset == MinWheelOffset && e.Delta < 0) || (_wheelOffset == MaxWheelOffset && e.Delta > 0)) { return; } _wheelOffset += e.Delta / 120; if (_wheelOffset < MinWheelOffset) { _wheelOffset = MinWheelOffset; } else if (_wheelOffset > MaxWheelOffset) { _wheelOffset = MaxWheelOffset; } double oldScale = _curScaleTransform.ScaleX; double newScale = Math.Log(1 + ((_wheelOffset) / 10d)) * 2d; //Calculate current viewing window onto the content Point topLeftContentSpace = TranslatePoint(new Point(0, 0), Children[0]); Point bottomRightContentSpace = TranslatePoint(new Point(ActualWidth, ActualHeight), Children[0]); Rect curView = new Rect { Location = topLeftContentSpace, Size = new Size(bottomRightContentSpace.X - topLeftContentSpace.X, bottomRightContentSpace.Y - topLeftContentSpace.Y) }; //Mouse position as a fraction of the view size Point viewSpaceMousePos = e.GetPosition(this); Point relZoomPoint = new Point { X = viewSpaceMousePos.X / this.ActualWidth, Y = viewSpaceMousePos.Y / this.ActualHeight }; //Calculate new viewing window Rect newView = ZoomView(curView, oldScale, newScale, relZoomPoint); //Calculate new content offset based on the new view Point newOffset = new Point(-newView.X * newScale, -newView.Y * newScale); //Calculate new viewing window scale ScaleTransform newScaleTransform = new ScaleTransform { ScaleX = newScale, ScaleY = newScale }; var zoomEvent = new ZoomEventArgs(e, _curScaleTransform, newScaleTransform, newOffset); Zoom?.Invoke(this, zoomEvent); ApplyZoomToChildren(zoomEvent); _curScaleTransform = newScaleTransform; }