Search code examples
c#xamlwinui-3winui

ScrollViewer does not adjust accordingly to image scaling


I'm working on a document viewer for a WinUI application.

In general it works, except that the scroll viewer height does not change.

So when zooming in the image, the scroll viewer does not change and so the image can't be scrolled to vertical end.

Do you have an idea or solution to that issue ?

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <!-- Image -->
    <ScrollViewer
        Grid.Row="1"
        PointerWheelChanged="ZoomByMouseWheel"
        HorizontalScrollBarVisibility="Auto"
        VerticalScrollBarVisibility="Auto">

        <Image 
            Height="Auto"
            x:Name="PreviewImage"
            RenderTransformOrigin="0.5,0.5">

            <ui:Effects.Shadow>
                <media:AttachedCardShadow Offset="4" CornerRadius="0"/>
            </ui:Effects.Shadow>

            <Image.RenderTransform>
                <TransformGroup>
                    <ScaleTransform ScaleX="0.01" ScaleY="0.01" />
                    <ScaleTransform>
                        <ScaleTransform.ScaleX>
                            <Binding
                                ElementName="ZoomSlider"
                                Mode="OneWay"
                                Path="Value" />
                        </ScaleTransform.ScaleX>
                        <ScaleTransform.ScaleY>
                            <Binding
                                ElementName="ZoomSlider"
                                Mode="OneWay"
                                Path="Value" />
                        </ScaleTransform.ScaleY>
                    </ScaleTransform>
                </TransformGroup>
            </Image.RenderTransform>
        </Image>
    </ScrollViewer>

Solution

  • The ScrollViewer has its own zooming feature. This is the minimal code that works:

    MainPage.xaml

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
    
        <Slider
            ValueChanged="ZoomSlider_ValueChanged"
            Value="1" />
    
        <ScrollViewer
            x:Name="ScrollViewerControl"
            Grid.Row="1"
            HorizontalScrollBarVisibility="Auto"
            VerticalScrollBarVisibility="Auto"
            ZoomMode="Enabled">
    
            <Image Source="Assets/image.jpg" />
    
        </ScrollViewer>
    </Grid>
    

    MainPage.xaml.cs

    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            this.Loaded += MainPage_Loaded;
        }
    
        private void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            this.ScrollViewerControl.ChangeView(
                horizontalOffset: null,
                verticalOffset: null,
                zoomFactor: (float)0.1);
        }
    
        private void ZoomSlider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
        {
            if (this.ScrollViewerControl is null)
            {
                return;
            }
    
            this.ScrollViewerControl.ChangeView(
                horizontalOffset: null,
                verticalOffset: null,
                zoomFactor: (float)e.NewValue);
        }
    }