ScrollViewer的ScrollToRect动画效果

在IOS上UIScrollView,ScrollToRect这个函数很强大,能以动画的形式聚焦到指定区域。

Win8 上,ScrollViewer相对就弱小很多。相对ScrollToRect,需要分三步来实现,

1 ZoomToFactor,

2 ScrollToHorizontalOffset,

3 ScrollToVerticalOffset

而且没有动画效果。

 

添加动画的思路就是在外面设置一个

DependencyProperty,在

PropertyChangedCallback里进行ScrollToRect实际调用。

 

实现过程:

1,对page添加三个DependencyProperty

    public static DependencyProperty CurrentVerticalOffsetProperty =
            DependencyProperty.Register("CurrentVerticalOffset",
            typeof(double),
            typeof(SplitPage),
            new PropertyMetadata(0, new PropertyChangedCallback(OnVerticalChanged))
            );
        public static DependencyProperty CurrentHorizontalOffsetProperty =
            DependencyProperty.Register("CurrentHorizontalOffset",
            typeof(double),
            typeof(SplitPage),
            new PropertyMetadata(0, new PropertyChangedCallback(OnHorizontalChanged))
            );
        public static DependencyProperty CurrentZoomFactorProperty =
            DependencyProperty.Register("CurrentZoomFactor",
                    typeof(float),
                    typeof(SplitPage),
                    new PropertyMetadata(0, new PropertyChangedCallback(OnCurrentZoomFactor))
                    );

        private static void OnVerticalChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            SplitPage viewer = d as SplitPage;
            double dTop = Convert.ToDouble(e.NewValue);
            //System.Diagnostics.Debug.WriteLine(string.Format(@"OnVerticalChanged:{0}", dTop));
            viewer.itemDetail.ScrollToVerticalOffset(dTop * viewer.itemDetail.ZoomFactor);
        }
        public double CurrentVerticalOffset
        {
            get
            {
                return Convert.ToDouble(this.GetValue(CurrentVerticalOffsetProperty));
            }
            set
            {
                this.SetValue(CurrentVerticalOffsetProperty, value);
            }
        }

        public double CurrentHorizontalOffset
        {
            get { return Convert.ToDouble(this.GetValue(CurrentHorizontalOffsetProperty)); }
            set { this.SetValue(CurrentHorizontalOffsetProperty, value); }
        }

        private static void OnHorizontalChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            SplitPage viewer = d as SplitPage;
            double dLeft = Convert.ToDouble(e.NewValue);
            //System.Diagnostics.Debug.WriteLine(string.Format(@"OnHorizontalChanged:{0}", dLeft));
            viewer.itemDetail.ScrollToHorizontalOffset(dLeft * viewer.itemDetail.ZoomFactor);
        }


        public float CurrentZoomFactor
        {
            get { return Convert.ToSingle(this.GetValue(CurrentZoomFactorProperty)); }
            set { this.SetValue(CurrentZoomFactorProperty, value); }
        }
        private static void OnCurrentZoomFactor(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            try
            {
                SplitPage viewer = d as SplitPage;
                float zoomFactor = Convert.ToSingle(e.NewValue);
                //System.Diagnostics.Debug.WriteLine(string.Format(@"zoomFactor:{0}", zoomFactor));
                viewer.itemDetail.ZoomToFactor(zoomFactor);
            }
            catch
            {
                System.Diagnostics.Debug.WriteLine(string.Format(@"exception:zoomFactor"));
            }
        }


 

 

 

2,在page的xaml文件里,添加storyboard

<Storyboard x:Name="ZoomToFaceStoryBoard" Completed="ZoomToFaceStoryBoard_Completed">
            <DoubleAnimation x:Name="ZoomFactorAnimation"
                             EnableDependentAnimation ="True"
                             Storyboard.TargetName="pageRoot" 
                             Storyboard.TargetProperty="CurrentZoomFactor" 
                             Duration="0:0:0.5"></DoubleAnimation>
            <DoubleAnimation x:Name="CurrentHorizontalOffsetAnimation"
                             EnableDependentAnimation ="True"
                             Storyboard.TargetName="pageRoot" 
                             Storyboard.TargetProperty="CurrentHorizontalOffset" 
                             Duration="0:0:0.5"></DoubleAnimation>
            <DoubleAnimation x:Name="CurrentVerticalOffsetAnimation"
                             EnableDependentAnimation ="True"
                             Storyboard.TargetName="pageRoot" 
                             Storyboard.TargetProperty="CurrentVerticalOffset" 
                             Duration="0:0:0.5"></DoubleAnimation>

        </Storyboard>

3,对page,添加ScrollToRect方法:

       private void ScrollToRect(Rect rect)
        {
            float curZoomFactor = this.ScrollViewer.ZoomFactor;
            float desZoomFactor = (float)Math.Min(ScrollViewer.ViewportWidth / rect.Width, ScrollViewer.ViewportHeight / rect.Height);

            double curHorizontalOffsetInContent = ScrollViewer.HorizontalOffset / ScrollViewer.ZoomFactor;
            double curVerticalOffsetInContent = ScrollViewer.VerticalOffset / ScrollViewer.ZoomFactor;



            this.CurrentVerticalOffsetAnimation.From = curVerticalOffsetInContent;
            this.CurrentVerticalOffsetAnimation.To = rect.Top - (ScrollViewer.ViewportHeight / desZoomFactor - rect.Height) / 2;

            this.CurrentHorizontalOffsetAnimation.From = curHorizontalOffsetInContent;
            this.CurrentHorizontalOffsetAnimation.To = rect.Left - (ScrollViewer.ViewportWidth / desZoomFactor - rect.Width) / 2;

            this.ZoomFactorAnimation.From = curZoomFactor;
            this.ZoomFactorAnimation.To = desZoomFactor;



            ZoomToFaceStoryBoard.Begin();
        }


4,调用方法:

        private void testBtn_Click_1(object sender, RoutedEventArgs e)
        {

            AnimateZoomToRect(new Rect(100, 100, 400, 400));
        }


 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值