© 2026 Hedgehog Software, LLC

TwitterGitHubDiscord
More
CommunitiesDocsAboutTermsPrivacy
Search
Star
Setup for Free
C#C
C#•3y ago•
2 replies
hugeman

❔ "Zooming" a WPF ScrollViewer to the center of the view

So I made this control (whose parent is the ScrollViewer i'm talking about), that has a "TargetWidth" and "ZoomScale" property (Setting either results in the Width property being set to
TargetWidth * ZoomScale
TargetWidth * ZoomScale
)

I've got that implemented, but I've been struggling for the past 2 hours to implement a way to make it "zoom" towards the center of the view (as in, the ScrollViewer's view port, therefore including the current vertical and horizontal offset)

Could anyone help? Every attempt I either zooms way too far to the left/right, or it initially works as intended, but then gradually starts zooming towards the left or right

here's the mess of code I've been working with so far:

if (this.PART_ScrollViewer is ScrollViewer scroller) {
    double multiplier;
    if ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift) {
        multiplier = e.Delta > 0 ? 1.05 : 0.95;
    }
    else {
        multiplier = e.Delta > 0 ? 1.1 : 0.9;
    }
    double oldzoom = this.UnitZoom;
    double newzoom = TimelineUtils.ClampUnit(oldzoom * multiplier);
    this.UnitZoom = newzoom;
    newzoom = this.UnitZoom;
    {
        double full_horizontal_offset = scroller.HorizontalOffset / this.UnitZoom;
        double visible_pixels = newzoom * this.ActualWidth;
        double width_ratio = (scroller.ExtentWidth / newzoom) / this.ActualWidth;
        double width_ratio_1 = scroller.ExtentWidth / this.ActualWidth;
        double ratio_diff = width_ratio_1 / width_ratio;
        double pixels_difference = (this.ActualWidth / oldzoom) - (this.ActualWidth / newzoom);
        double actual_pixel_change = pixels_difference * newzoom;
        double side_ratio_x = (scroller.HorizontalOffset / 2) / full_horizontal_offset;
        double new_offset = full_horizontal_offset - actual_pixel_change;
        scroller.ScrollToHorizontalOffset(scroller.HorizontalOffset + new_offset);
        return;
    }
}
if (this.PART_ScrollViewer is ScrollViewer scroller) {
    double multiplier;
    if ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift) {
        multiplier = e.Delta > 0 ? 1.05 : 0.95;
    }
    else {
        multiplier = e.Delta > 0 ? 1.1 : 0.9;
    }
    double oldzoom = this.UnitZoom;
    double newzoom = TimelineUtils.ClampUnit(oldzoom * multiplier);
    this.UnitZoom = newzoom;
    newzoom = this.UnitZoom;
    {
        double full_horizontal_offset = scroller.HorizontalOffset / this.UnitZoom;
        double visible_pixels = newzoom * this.ActualWidth;
        double width_ratio = (scroller.ExtentWidth / newzoom) / this.ActualWidth;
        double width_ratio_1 = scroller.ExtentWidth / this.ActualWidth;
        double ratio_diff = width_ratio_1 / width_ratio;
        double pixels_difference = (this.ActualWidth / oldzoom) - (this.ActualWidth / newzoom);
        double actual_pixel_change = pixels_difference * newzoom;
        double side_ratio_x = (scroller.HorizontalOffset / 2) / full_horizontal_offset;
        double new_offset = full_horizontal_offset - actual_pixel_change;
        scroller.ScrollToHorizontalOffset(scroller.HorizontalOffset + new_offset);
        return;
    }
}
C# banner
C#Join
We are a programming server aimed at coders discussing everything related to C# (CSharp) and .NET.
61,871Members
Resources
Was this page helpful?

Similar Threads

Recent Announcements

Similar Threads

Costom ScrollViewer Wpf
C#CC# / help
2y ago
WPF ScrollViewer issues
C#CC# / help
3y ago
WPF running .ToString() of viewmodel instead of showing the coresponding view
C#CC# / help
16mo ago
'The viewmanager.activeview must be a view contained within the viewmanager.window profile'
C#CC# / help
4y ago