缩放后的Winrt ScrollViewer无法滚动整个图像

时间:2014-12-09 13:46:33

标签: c# xaml windows-runtime winrt-xaml

我使用c#/ xaml创建了一个Winrt(Windows 8.1)应用程序,我在其中显示图像。如果我想用触摸它来缩放这些图像它正在工作,但我不能完全滚动到右侧(垂直)。 一点点就会减少。

但如果我继续抚摸并向前移动我的手,我可以看到缺失的部分。如果我停止触摸图像会返回,我看不到丢失的部分。

<Grid Background="{ThemeResource BackgroundBrush}"
    DataContext="{Binding ShortcutItem}" x:Name="rootGrid">

    <Grid.RowDefinitions>
        <RowDefinition Height="140"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="70"/>
    </Grid.RowDefinitions>

    <!-- Header: Back button and page title -->
    <Grid  Grid.ColumnSpan="2">
        <!--Titel-->
        <!--Logo-->
    </Grid>

    <!--Content: Details for selected item -->
    <Grid x:Name="itemDetailGrid" 
          Margin="10,10,10,10" 
          Grid.Row="1"
          Grid.RowSpan="1" 
          DataContext="{Binding Source={StaticResource itemsViewSource}}">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <ScrollViewer 
        Grid.Row="1" 
        HorizontalScrollMode="Enabled"
        HorizontalScrollBarVisibility="Auto"
        VerticalScrollMode="Enabled"
        VerticalScrollBarVisibility="Auto"
        ZoomMode="Enabled"
        MinZoomFactor="1.0"
        MaxZoomFactor="2.0">
            <ItemsControl 
                ItemsSource="{Binding DocumentPages}">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <Grid >
                                <Border BorderBrush="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}" BorderThickness="0,0,0,5" >
                                    <Image Source="{Binding Content}" Stretch="None" />
                                </Border>
                            </Grid>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
            </ItemsControl >
        </ScrollViewer>
    </Grid>

    <!--Footer-->

</Grid>

我用填充,边距和其他布局选项测试了很多东西,但是我无法全面查看。

我希望有人可以帮助我。

1 个答案:

答案 0 :(得分:1)

试试这个:

using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;

namespace MyProject.Extensions
{
    public class ImageInScrollView : DependencyObject
    {
        public static readonly DependencyProperty HandlerEnabledProperty =
            DependencyProperty.RegisterAttached("HandlerEnabled", typeof(bool), typeof(Image), new PropertyMetadata(false, OnHandlerEnabledChanged));
        public static void SetHandlerEnabled(DependencyObject obj, object value)
        {
            obj.SetValue(HandlerEnabledProperty, value);
        }
        public static object GetHandlerEnabled(DependencyObject obj)
        {
            return obj.GetValue(HandlerEnabledProperty);
        }
        private static void OnHandlerEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Image image = (d as Image);
            bool HandlerEnabled;
            bool.TryParse(e.NewValue.ToString(), out HandlerEnabled);
            if (HandlerEnabled)
            {
                image.ImageOpened -= ImageOpenedInScrollViewer;
                image.ImageOpened += ImageOpenedInScrollViewer;
                image.Stretch = Stretch.None;
            }
            else
            {
                image.ImageOpened -= ImageOpenedInScrollViewer;
            }
        }

        private static void ImageOpenedInScrollViewer(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            Image image = sender as Image;

            ScrollViewer parentScrollView = GetParentScrollView(image.Parent as FrameworkElement);
            if(parentScrollView == null)
                return;

            parentScrollView.IsScrollInertiaEnabled = true;
            parentScrollView.SizeChanged -= ParentScrollView_SizeChanged;
            parentScrollView.SizeChanged += ParentScrollView_SizeChanged;

            ImageUpdateHandler(image, parentScrollView);
        }

        private static void ImageUpdateHandler(Image image, ScrollViewer scrollView)
        {
            if(image == null || scrollView == null)
                return;

            if (image.ActualWidth < 0.001 || image.ActualHeight < 0.001)
            {
                image.SizeChanged += image_SizeChanged;
                return;
            }

            image.Width = image.ActualWidth;
            image.Height = image.ActualHeight;

            float minZoomFactor = (float)Math.Min(
                    scrollView.ViewportWidth / image.ActualWidth,
                    scrollView.ViewportHeight / image.ActualHeight);
            if (Math.Abs(scrollView.MinZoomFactor - minZoomFactor) < 0.001)
                return;

            scrollView.MinZoomFactor = minZoomFactor;
            scrollView.ChangeView(null, null, scrollView.MinZoomFactor, true);
        }

        static void image_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            var image = sender as Image;
            image.SizeChanged -= image_SizeChanged;
            ScrollViewer parentScrollView = GetParentScrollView(image.Parent as FrameworkElement);
            if (parentScrollView == null)
                return;

            ImageUpdateHandler(image, parentScrollView);
        }

        static void ParentScrollView_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            var scrollView = sender as ScrollViewer;
            var image = Helper.FindFirstChild<Image>(scrollView);
            ImageUpdateHandler(image, scrollView);
        }

        private static ScrollViewer GetParentScrollView(FrameworkElement parent)
        {
            ScrollViewer parentScrollView;
            while ((parentScrollView = parent as ScrollViewer) == null)
            {
                parent = parent.Parent as FrameworkElement;
                if (parent == null)
                    return null;
            }
            return parentScrollView;
        }
    }
}

在xaml中使用:

<ScrollViewer ZoomMode="Enabled" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
    <Image Source="your_source" extensions:ImageInScrollView.HandlerEnabled="true"/>
</ScrollViewer>
不要忘记在xaml中添加名称空间:

xmlns:extensions="using:MyProject.Extensions"

you might find this answer interesting