Question

I have an image inside a ScrollViewer. When I set image width larger, HorizontalScrollBar appeared. Then I set image Width smaller than ScrollViewer With but this ScrollBar still appear, like this:

                IMG
How I can fix this problem? Thank you!

<Grid>
    <ScrollViewer
        Name="sv"
        HorizontalScrollBarVisibility="Auto"
        VerticalScrollBarVisibility="Auto"
        PreviewMouseWheel="sv_PreviewMouseWheel">
        <Image Name="img"/>
    </ScrollViewer>
</Grid>

Code:

    void sv_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
    {
        if ((System.Windows.Forms.Control.ModifierKeys & System.Windows.Forms.Keys.Control) != System.Windows.Forms.Keys.Control) base.OnMouseWheel(e);
        else
        {
            if (e.Delta > 0)
            {
                if (img.ActualHeight < img.Source.Height * 5)
                {
                    double h2 = img.Height = img.ActualHeight * 1.1;
                    double w2 = img.Width = img.Source.Width * h2 / img.Source.Height;
                }
            }

            // PROBLEM HERE:

            else if (img.ActualHeight > 100) img.Height = img.ActualHeight / 1.1;
        }
    }
Was it helpful?

Solution

The problem is that you're not setting the Image control's Width property when you're scaling the image down. The image control actually automatically maintains the aspect ratio (the Stretch property is set to Uniform by default). But while the image resizes, the control itself keeps the size you set during scale up. Also note I've corrected your modifier keys check to use WPF instead of Windows Forms:

void sv_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
    if (Keyboard.Modifiers.HasFlag(ModifierKeys.Control))
    {
        double? h2 = null;
        if (e.Delta > 0)
        {
            if (img.ActualHeight < img.Source.Height * 5)
            {
                h2 = img.Height = img.ActualHeight * 1.1;
            }
        }
        else if (img.ActualHeight > 100)
        {
          h2 = img.Height = img.ActualHeight / 1.1;
        }

        if (h2 != null)
        {
             img.Width = img.Source.Width * h2.Value / img.Source.Height;
        }
    }
}

Another solution can be to use a transform to scale the image.

XAML

<Image Name="img"
       HorizontalAlignment="Center"
       VerticalAlignment="Center">
    <Image.LayoutTransform>
        <ScaleTransform x:Name="imageScale" />
    <Image.LayoutTransform>
</Image>

C#

void sv_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
    if (Keyboard.Modifiers.HasFlag(ModifierKeys.Control))
    {
        e.Handled = true; // stops scrolling due to wheel

        if (e.Delta > 0)
        {
            if (imageScale.ScaleX < 5)
            {
                imageScale.ScaleX *= 1.1;
                imageScale.ScaleY *= 1.1;
            }
        }
        else
        {
            imageScale.ScaleX /= 1.1;
            imageScale.ScaleY /= 1.1;
        }
    }
}

You can use other transforms as well, such as rotate. Read more about it on MSDN.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top