Introduction
Beholds...
Smooth Sliding & Animated Scrollbar! Brilliant!!!! Isn't it?!
Perhaps many of you have been thinking of something like that and then you went to Google it!
And of course, you thought it should be easy to make stuff like that in WPF!
... and just after some pathetic and hopeless moments, you face the unknown world of confusing codes, random answers, new controllers and ...!
Well, don't give up! There's still a really easy way to create it in a Perfect Shape!
Result / GIF 30fps
Why You Shouldn't Use Custom Control For Now?
- If you're an expert:
Forget it! Yeah I was just kidding :\ you can build everything you want!
A Custom Control or even a Serial Killer Robot Rexter! :D
- If you're not an expert:
All themes are mounted on a specific resource in WPF and if you create your own custom control, it doesn't support the general resources you have to add them one by one on your own !
Creating the Bases
First of all, create a Window and apply your theme [mahapps, materialDesign, ModernUI, etc.]
// I Use My Custom Theme
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>
Remember to use "Auto
" height on everything that is inside the scrollview
.
Going to the Next Stage!
- Now, you just need to duplicate
scrollview
to 2 Scrollview
! - Rename the first one to "
main_scroll
" and second one to "scroll_animator
". - Now, change the child of
scroll_animator
to an empty group
. - Bind the
Height
property of empty group
to the ActualHeight
property of RichTextBox is inside main_scroll. - Well done !
Time to Code!
- Before we start this section, you need to know WPF standard
scrollview
doesn't support direct value setting by code in Offset, it's a function like set it to 1, 2, 3! It sucks! - Then we need to add the offset property manually, it's really easy to create!
- Add a class to your project root. Add Item > Class > ScrollViewFixer.cs
- Add this code to your class & save it !
ScrollViewFixer.cs
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);
}
}
}
+ Remember, add this code to your cs file Namespace.
- Now let's finish it ...
- Change
main_scroll
like this:
Replace:
<ScrollViewer x:Name="main_scroll" Margin="0">
with:
<fixed_scrl:ScrollViewFixer x:Name="main_scroll" Margin="0,0,18,0"
VerticalScrollBarVisibility="Hidden">
- Add the name space at the top of window in xmlns:
xmlns:fixed_scrl="clr-namespace:Scroll_Fixer_Namespace"
Remember the "Scroll_Fixer_Namespace
" is your namespace of "ScrollViewFixer.cs" file.
namespace Scroll_Fixer_Namespace
{
public class ScrollViewFixer : ScrollViewer
{ ....
- Resize
scroll_animator
to just "Scroll Bar" box size. - Time to animate!
Process:
- Add a ScrollChanged Event to scroll_animator.
- Create Animator Code (don't forget to add
using System.Windows.Media.Animation;
):
<scroll_animator> ScrollChanged Event
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);
}
I'm a big fan of PowerEase. :D If you want, change it to normal Ease for smoother result.
Well done! Now if you change your scrollbar, it's smooth and so fantastic! BUT BUGGY :|
Now we're going to fix ...
Fixing Scrollview Issues
A> Fixing Mousewheel Scrolling
- Add
PreviewMouseWheel
to your main_scroll
. - Disable Handler and connect it to
Animator
. It's like:
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> Fixing Dynamic Content
If you're using a dynamic framework element like ListBox
, Editbox
, Textbox
, RichText
, Stackpanel
, you need to set the scroll bar update on adding things, changes ...
- Create a function
UpdateAnimator()
to your code behind:
private void UpadeUpdateAnimator()
{
scroll_animator.ScrollToEnd();
}
- Now add
SizeChanged
to your main_scroll
and just insert UpadeUpdateAnimator();
to it!
private void Content_Size_Change(object sender, SizeChangedEventArgs e)
{
if (this.IsLoaded) { UpadeUpdateAnimator();
}
}
- And in every update you make in Main
ScrollView
Contents, just use a little UpadeUpdateAnimator();
after works!
We're done! Enjoy from your amazing, smoothed, animated ScrollView!!!
History
- 4th January, 2020: Initial version