65.9K
CodeProject 正在变化。 阅读更多。
Home

[WPF] 创建动画/平滑滚动条的最简单方法

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.78/5 (11投票s)

2018年8月9日

CPOL

3分钟阅读

viewsIcon

19032

这是在WPF平台(Windows Presentation Foundation)上创建动画和流畅滑动滚动查看器的最佳、最漂亮、最简单的方法。

引言

请看...

流畅滑动 & 动画滚动条!太棒了!!!!不是吗?!

也许你们很多人一直在思考类似的事情,然后你们就去Google了!

当然,你们认为在WPF中制作这样的东西应该很容易!

…… 就在一些可悲和绝望的时刻之后,你面对了混乱的代码、随机的答案、新的控制器和……的未知世界!

好吧,不要放弃! 仍然有一种非常简单的方法可以在完美形状中创建它!

结果/GIF 30fps

为什么现在你不应该使用自定义控件?

  • 如果你是专家

    忘记它! 是的,我只是开玩笑的 :\ 你可以构建你想要的任何东西!

    一个自定义控件,甚至是杀人机器人Rexter! :D

  • 如果你不是专家

    所有主题都安装在WPF中的特定资源上,如果你创建自己的自定义控件,它不支持你必须一个接一个添加的通用资源!

创建基础

首先,创建一个Window并应用你的主题 [mahapps, materialDesign, ModernUI, 等等.]

// 我使用我的自定义主题

Window XAML

<Window x:Class="Tutorial_Projects.SmoothScroll_Window"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Tutorial_Projects"
        Title="Easiest Way to Create a Animated/Smoothed Scroll Bar | 
               By NeoTrix2000" Height="338.866" Width="553.846" ResizeMode="NoResize" 
               WindowStartupLocation="CenterScreen">
    
<Grid Background="#FF232323">
        <ScrollViewer Margin="0">
            <RichTextBox Foreground="#FF959595" BorderBrush="{x:Null}" 
             Background="#FF212121" IsReadOnly="True" IsHitTestVisible="False">
                <FlowDocument>
                    <Paragraph>
                        <Run Foreground="#FF0E95AA" FontWeight="Bold" FontSize="18"/>
                    </Paragraph>
                    <Paragraph>
                        <Run Foreground="#FF0E95AA" FontWeight="Bold" 
                         FontSize="18" Text="Sed ut perspiciatis unde omnis iste natus 
                         error sit voluptatem accusantium doloremque"/>
                    </Paragraph>
                    <Paragraph>
                        <Run Foreground="#FF0E95AA" 
                        FontWeight="Bold" FontSize="18" Text=" "/>
                        <Run Text="laudantium, totam rem aperiam, 
                         eaque ipsa quae ab illo inventore veritatis et quasi architecto 
                         beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia 
                         voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur 
                         magni dolores eos qui ratione voluptatem sequi nesciunt. 
                         Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, 
                         consectetur, adipisci velit, sed quia non numquam eius modi tempora 
                         incidunt ut labore et dolore magnam aliquam quaerat voluptatem. 
                         Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis 
                         suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? 
                         Quis autem vel eum iure reprehenderit qui in ea voluptate velit 
                         esse quam nihil molestiae consequatur, vel illum qui dolorem eum 
                         fugiat quo voluptas nulla pariatur? At vero eos et accusamus et 
                         iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum 
                         deleniti atque corrupti quos dolores et quas molestias excepturi 
                         sint occaecati cupiditate non provident, similique sunt in culpa 
                         qui officia deserunt mollitia animi, id est laborum et dolorum fuga. 
                         Et harum quidem rerum facilis est et expedita distinctio. 
                         Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil 
                         impedit quo minus id quod maxime placeat facere possimus, 
                         omnis voluptas assumenda est, omnis dolor repellendus. 
                         Temporibus autem quibusdam et aut officiis debitis aut rerum 
                         necessitatibus saepe eveniet ut et voluptates repudiandae sint 
                         et molestiae non recusandae. Itaque earum rerum hic tenetur a 
                         sapiente delectus, ut aut reiciendis voluptatibus maiores alias 
                         consequatur aut perferendis doloribus asperiores repellat. 
                         Sed ut perspiciatis unde omnis iste natus error sit "/>
                    </Paragraph>
                    <Paragraph>
                        <Run Text="voluptatem accusantium doloremque laudantium, 
                        totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et 
                        quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam 
                        voluptatem quia voluptas sit aspernatur aut odit aut fugit, 
                        sed quia consequuntur magni dolores eos qui ratione 
                        voluptatem sequi nesciunt. 
                        Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, 
                        consectetur, adipisci velit, 
                        sed quia non numquam eius modi tempora incidunt 
                        ut labore et dolore magnam aliquam quaerat voluptatem. 
                        Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis 
                        suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? 
                        Quis autem vel eum iure reprehenderit qui in ea voluptate velit 
                        esse quam nihil molestiae consequatur, vel illum qui dolorem eum 
                        fugiat quo voluptas nulla pariatur? At vero eos et accusamus et 
                        iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum 
                        deleniti atque corrupti quos dolores et quas molestias excepturi sint 
                        occaecati cupiditate non provident, similique sunt in culpa qui 
                        officia deserunt mollitia animi, id est laborum et dolorum fuga. 
                        Et harum quidem rerum facilis est et expedita distinctio. 
                        Nam libero tempore, cum soluta nobis est eligendi optio 
                        cumque nihil impedit quo minus id quod maxime placeat facere possimus, 
                        omnis voluptas assumenda est, omnis dolor repellendus. 
                        Temporibus autem quibusdam et aut officiis debitis aut rerum 
                        necessitatibus saepe eveniet ut et voluptates repudiandae sint 
                        et molestiae non recusandae. Itaque earum rerum hic tenetur 
                        a sapiente delectus, ut aut reiciendis voluptatibus "/>
                    </Paragraph>
                    <Paragraph>
                        <Run Text="maiores alias consequatur aut perferendis 
                        doloribus asperiores repellat. Sed ut perspiciatis unde omnis 
                        iste natus error sit voluptatem accusantium doloremque laudantium, 
                        totam rem aperiam, eaque ipsa quae ab illo inventore veritatis 
                        et quasi architecto beatae vitae dicta sunt explicabo. 
                        Nemo enim ipsam voluptatem quia voluptas sit aspernatur 
                        aut odit aut fugit, sed quia consequuntur magni dolores eos qui 
                        ratione voluptatem sequi nesciunt. Neque porro quisquam est, 
                        qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, 
                        sed quia non numquam eius modi tempora incidunt ut labore et 
                        dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, 
                        quis nostrum exercitationem ullam corporis suscipit laboriosam, 
                        nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure 
                        reprehenderit qui in ea voluptate velit esse quam nihil molestiae 
                        consequatur, vel illum qui dolorem eum fugiat quo voluptas 
                        nulla pariatur? At vero eos et accusamus et iusto odio dignissimos 
                        ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti 
                        quos dolores et quas molestias excepturi sint occaecati cupiditate 
                        non provident, similique sunt in culpa qui officia deserunt 
                        mollitia animi, id est laborum et dolorum fuga. Et harum quidem 
                        rerum facilis est et expedita distinctio. Nam libero tempore, 
                        cum soluta nobis est eligendi optio cumque nihil impedit quo minus 
                        id quod maxime placeat facere possimus, omnis voluptas assumenda est, 
                        omnis dolor repellendus. Temporibus autem quibusdam et aut officiis 
                        debitis aut rerum necessitatibus saepe eveniet ut et voluptates 
                        repudiandae sint et molestiae non recusandae. Itaque earum rerum 
                        hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus 
                        maiores alias consequatur aut perferendis doloribus asperiores 
                        repellat.Sed ut perspiciatis unde omnis iste natus error sit 
                        voluptatem accusantium doloremque laudantium, totam rem aperiam, 
                        eaque ipsa quae ab illo inventore veritatis et quasi architecto 
                        beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia 
                        voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur 
                        magni dolores eos qui ratione voluptatem sequi nesciunt. 
                        Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, 
                        consectetur, adipisci velit, sed quia non numquam eius modi tempora 
                        incidunt ut labore et dolore magnam aliquam quaerat voluptatem. 
                        Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis 
                        suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? 
                        Quis autem vel eum iure reprehenderit qui in ea voluptate velit 
                        esse quam nihil molestiae consequatur, vel illum qui dolorem eum 
                        fugiat quo voluptas nulla pariatur? At vero eos et accusamus et iusto 
                        odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti 
                        atque corrupti quos dolores et quas molestias excepturi sint"/>
                    </Paragraph>
                </FlowDocument>
            </RichTextBox>
        </ScrollViewer>
    </Grid>
</Window>

记住在scrollview内部的所有内容上使用“Auto”高度。

进入下一阶段!

  1. 现在,你只需要将scrollview复制到 2 个 Scrollview !
  2. 将第一个重命名为“main_scroll”,第二个重命名为“scroll_animator”。
  3. 现在,将scroll_animator的子元素更改为空组
  4. 空组Height属性绑定到RichTextBox inside main_scroll.ActualHeight属性。
  5. 做得好!

是时候写代码了!

  • 在我们开始这部分之前,你需要知道WPF标准scrollview不支持通过代码直接设置Offset值,它是一个像设置为1、2、3这样的函数! 它太糟糕了!
  • 然后我们需要手动添加offset属性,这真的很容易创建!
    1. 将一个类添加到你的项目根目录。添加 Item > Class > ScrollViewFixer.cs
    2. 将此代码添加到你的类中并保存它!

ScrollViewFixer.cs

//// After Namespace
public class ScrollViewFixer: ScrollViewer {
 public static DependencyProperty v_offsetProperty = DependencyProperty.Register
       ("v_offset", typeof(double), typeof(ScrollViewFixer), 
       new PropertyMetadata(new PropertyChangedCallback(OnVerticalChanged)));
 public static DependencyProperty h_offset = DependencyProperty.Register
 ("h_offset", typeof(double), typeof(ScrollViewFixer), 
 new PropertyMetadata(new PropertyChangedCallback(OnHorizontalChanged)));
 
private static void OnVerticalChanged(DependencyObject ss_dependency, 
DependencyPropertyChangedEventArgs ss_evenargs) {
  ScrollViewFixer viewer = ss_dependency as ScrollViewFixer;
  viewer.ScrollToVerticalOffset((double) ss_evenargs.NewValue);
 } 

private static void OnHorizontalChanged(DependencyObject ss_dependency, 
DependencyPropertyChangedEventArgs ss_evenargs) {
  ScrollViewFixer viewer = ss_dependency as ScrollViewFixer;
  viewer.ScrollToHorizontalOffset((double) ss_evenargs.NewValue);
 }

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

 public double v_offset {
  get {
   return (double) this.GetValue(v_offsetProperty);
  }
  set {
   this.SetValue(v_offsetProperty, value);
  }
 }
}
+ 记住,将此代码添加到你的cs文件命名空间中。
  • 现在让我们完成它...
  • 像这样更改main_scroll

    替换

     <ScrollViewer x:Name="main_scroll" Margin="0">

     <fixed_scrl:ScrollViewFixer x:Name="main_scroll" Margin="0,0,18,0" 
      VerticalScrollBarVisibility="Hidden">
    • 在xmlns中的window顶部添加命名空间
     xmlns:fixed_scrl="clr-namespace:Scroll_Fixer_Namespace"

    记住“Scroll_Fixer_Namespace”是你的“ScrollViewFixer.cs”文件的命名空间。

    namespace Scroll_Fixer_Namespace
    {
        public class ScrollViewFixer : ScrollViewer
        { ....
  • scroll_animator调整为仅“滚动条”框大小。
  • 是时候动画了!
    进程
    1. ScrollChanged 事件添加到 scroll_animator.
    2. 创建动画器代码(不要忘记添加 using System.Windows.Media.Animation;

<scroll_animator> ScrollChanged 事件

private void scroll_animator_ScrollChanged(object sender, ScrollChangedEventArgs e) {
 PowerEase _ease = new PowerEase();
 _ease.EasingMode = EasingMode.EaseOut;
 _ease.Power = 8;
 DoubleAnimation scrollanim = new DoubleAnimation
                      (scroll_animator.VerticalOffset, TimeSpan.FromSeconds(2));
 scrollanim.EasingFunction = _ease;
 main_scroll.BeginAnimation
                      (Scroll_Fixer_Namespace.ScrollViewFixer.v_offset_property, scrollanim);
}
我是PowerEase的忠实粉丝。 :D 如果你想,将其更改为normal Ease以获得更平滑的结果。

做得好!现在如果你改变你的滚动条,它是平滑的,而且非常棒!但有BUG :|

现在我们要修复 ...

修复 Scrollview 问题

A> 修复鼠标滚轮滚动

  • PreviewMouseWheel添加到你的main_scroll
  • 禁用处理程序并将其连接到Animator。 就像这样
     private void MouseWheel_Fix(object sender, MouseWheelEventArgs e)
     { e.Handled = true;}
    • 额外模式
    private void MouseWheel_Fix(object sender, MouseWheelEventArgs e) {
    
     e.Handled = true;
     int Division_Unit = 5;
     scroll_animator.ScrollToVerticalOffset((scroll_animator.VerticalOffset + 
                                           ((e.Delta * -1) / Division_Unit)));
    }

B> 修复动态内容

如果你使用像ListBoxEditboxTextboxRichTextStackpanel这样的动态框架元素,你需要设置滚动条更新,以便在添加内容、更改内容时...更新。

  • 在你的代码背后创建一个函数UpdateAnimator()
            private void UpadeUpdateAnimator()
            {
                  scroll_animator.ScrollToEnd();
            }
  • 现在将SizeChanged添加到你的main_scroll,只需将其插入UpadeUpdateAnimator();
            private void Content_Size_Change(object sender, SizeChangedEventArgs e)
            {
                if (this.IsLoaded) {  /// Startup Fix
                    UpadeUpdateAnimator();
                }
    
            }
  • 并且在你在Main ScrollView内容中进行的每次更新中,只需在工作完成后使用一个小UpadeUpdateAnimator();
我们完成了!从你惊人的、平滑的、动画的ScrollView中享受吧!!!

历史

  • 2020年1月4日:初始版本
© . All rights reserved.