前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >让 ScrollViewer 的滚动带上动画

让 ScrollViewer 的滚动带上动画

作者头像
walterlv
发布2018-09-18 14:56:45
9510
发布2018-09-18 14:56:45
举报

让 ScrollViewer 的滚动带上动画

2017-12-19 12:19

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


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

代码语言:javascript
复制
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 方法。这样,便能够通过动画改变属性的方式来调用这两个方法。

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

代码语言:javascript
复制
<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

代码语言:javascript
复制
<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

本文会经常更新,请阅读原文: https://walterlv.com/post/scrollviewer-animation.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 吕毅 (包含链接: https://walterlv.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 (walter.lv@qq.com)

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-12-19 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 让 ScrollViewer 的滚动带上动画
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档