在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));
}