WPF 的 ScrollViewer 没有水平滚动和垂直滚动的属性 HorizontalScrollOffset VerticalScrollOffset,只有水平滚动和垂直滚动的方法 ScrollToHorizontalOffset ScrollToVerticalOffset,那么怎么给滚动过程加上动画呢?


既然没有属性,那我们加个属性好了,反正附加属性就是用来干这个事儿的。

namespace Walterlv
{
public static class ScrollViewerBehavior
{
public static readonly DependencyProperty HorizontalOffsetProperty = DependencyProperty.RegisterAttached("HorizontalOffset", typeof(double), typeof(ScrollViewerBehavior), new UIPropertyMetadata(0.0, OnHorizontalOffsetChanged));
public static void SetHorizontalOffset(FrameworkElement target, double value) => target.SetValue(HorizontalOffsetProperty, value);
public static double GetHorizontalOffset(FrameworkElement target) => (double)target.GetValue(HorizontalOffsetProperty);
private static void OnHorizontalOffsetChanged(DependencyObject target, DependencyPropertyChangedEventArgs e) => (target as ScrollViewer)?.ScrollToHorizontalOffset((double)e.NewValue); public static readonly DependencyProperty VerticalOffsetProperty = DependencyProperty.RegisterAttached("VerticalOffset", typeof(double), typeof(ScrollViewerBehavior), new UIPropertyMetadata(0.0, OnVerticalOffsetChanged));
public static void SetVerticalOffset(FrameworkElement target, double value) => target.SetValue(VerticalOffsetProperty, value);
public static double GetVerticalOffset(FrameworkElement target) => (double)target.GetValue(VerticalOffsetProperty);
private static void OnVerticalOffsetChanged(DependencyObject target, DependencyPropertyChangedEventArgs e) => (target as ScrollViewer)?.ScrollToVerticalOffset((double)e.NewValue);
}
}

我们在属性的变更通知中调用了 ScrollToHorizontalOffsetScrollToVerticalOffset 方法。这样,便能够通过动画改变属性的方式来调用这两个方法。

那么现在我们就加上动画:

<Storyboard x:Key="ScrollStoryboard">
<DoubleAnimation Storyboard.TargetName="ScrollViewer" Storyboard.TargetProperty="(walterlv:ScrollViewerBehavior.HorizontalOffset)"
From="0" To="500" Duration="0:0:0.6">
<DoubleAnimation.EasingFunction>
<CircleEase EasingMode="EaseOut"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>

添加一些用于测试的按钮和 ScrollViewer

<ScrollViewer Grid.Row="0" Grid.RowSpan="2" Grid.Column="0" Grid.ColumnSpan="3" x:Name="ScrollViewer"
HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible">
<Image Source="https://walterlv.github.io/static/posts/2017-12-09-21-19-50.png" Width="1000"/>
</ScrollViewer>
<Button Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" x:Name="ConnectionDestination"
VerticalAlignment="Bottom" Height="50" Content="动画目标" Panel.ZIndex="1">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard Storyboard="{StaticResource ScrollStoryboard}"/>
</EventTrigger>
</Button.Triggers>
</Button>

现在,我们点击按钮,就可以看到 ScrollViewer 的滚动动画生效了,如下:


额外的,如果希望这个附加属性能够附加到 ListView 或者 ListBox 中,则需要修改 ScrollViewerBehavior 类,然后在 OnHorizontalOffsetChangedOnVerticalOffsetChanged 方法中判断 ListViewListBox,然后在其中寻找可视元素子级 ScrollViewer

最新文章

  1. 解决CentOS无法解析域名的问题
  2. Apache+PHP 配置随笔
  3. windows下关闭进程
  4. 使用AutoMapper
  5. HW2.19
  6. HDU 3853 期望概率DP
  7. define a class for a linked list and write a method to delete the nth node.
  8. isset()和empty()的区别
  9. AJAX编程实践
  10. C#读取shp文件并获取图形保存到sde要素类中(不使用ESRI的类库,纯c#实现)
  11. canvas save()和canvas restore()状态的保存和恢复使用方法及实例
  12. [TensorFlow笔记乱锅炖] tf.multinomial(logits, num_samples)使用方法
  13. Openstack官网文档简介
  14. easyui combobox下拉列表的多选值
  15. 面向对象【day07】:多态(九)
  16. [PGM] Markov Networks
  17. jquery_opacity_css透明
  18. CacheDependency 的使用方法
  19. Java之IO流(字节流,字符流)
  20. matlab中将矩阵按照行打乱顺序的一个例子

热门文章

  1. R语言系列:自定义function
  2. SSH两种验证方式原理
  3. js三种对话框
  4. python中装饰器的执行细节
  5. ctci1.3
  6. python PIL/Pillow图像扩展、复制、粘贴处理
  7. C# 过滤HTML,脚本,数据库关键字,特殊字符
  8. 清理网页中的HTML
  9. Visual Studio 2017 序列号 Key 激活码 VS2017 注册码
  10. docker下rabbitMQ高可用集群部署