Skip to content

Instantly share code, notes, and snippets.

@sm-abdullah
Last active January 3, 2017 16:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sm-abdullah/bbe03936007f28179f61adf7864c0afc to your computer and use it in GitHub Desktop.
Save sm-abdullah/bbe03936007f28179f61adf7864c0afc to your computer and use it in GitHub Desktop.
InfiniteScrollViewer lazy Data Loading Scrolling
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Markup;
[assembly: XmlnsDefinition("http://codingsack.com/wpf/InfiniteScrollViewer", "InfiniteScrollViewerControl")]
[assembly: XmlnsPrefix("http://codingsack.com/wpf/InfiniteScrollViewer", "cs")]
namespace InfiniteScrollViewerControl
{
public class InfiniteScrollViewer : ScrollViewer
{
static InfiniteScrollViewer()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(InfiniteScrollViewer), new FrameworkPropertyMetadata(typeof(InfiniteScrollViewer)));
}
public static DependencyProperty CommandProperty = DependencyProperty.Register("Command", typeof(ICommand), typeof(InfiniteScrollViewer));
public static DependencyProperty CommandParameterProperty = DependencyProperty.Register("CommandParameter", typeof(object), typeof(InfiniteScrollViewer));
public static DependencyProperty ScrollResetProperty = DependencyProperty.Register("ScrollReset", typeof(bool), typeof(InfiniteScrollViewer), new PropertyMetadata(new PropertyChangedCallback(OnScrollResetPropertyChanged)));
public static DependencyProperty IsLoadingProperty = DependencyProperty.Register("IsLoading", typeof(bool), typeof(InfiniteScrollViewer), new PropertyMetadata(new PropertyChangedCallback(OnScrollIsLoadingPropertyChanged)));
public static DependencyProperty LoadingContentProperty = DependencyProperty.Register("LoadingContent", typeof(object), typeof(InfiniteScrollViewer), new PropertyMetadata());
private static void OnScrollResetPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var scrollviewer = sender as InfiniteScrollViewer;
//if user want to set the scroll at top.
//then he must changed ScrollReset =true
scrollviewer.ScrollToVerticalOffset(0);
}
private static void OnScrollIsLoadingPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var scrollviewer = sender as InfiniteScrollViewer;
if (scrollviewer.IsLoading == false)
{
var ui = scrollviewer.LoadingContent as FrameworkElement;
if (ui != null)
{
//when IsLading is False then Hide the LoadingContent as well as Move Scroll to Up
scrollviewer.ScrollToVerticalOffset(scrollviewer.VerticalOffset - ui.DesiredSize.Height - ui.DesiredSize.Height);
}
}
}
public ICommand Command
{
get
{
return (ICommand)GetValue(CommandProperty);
}
set
{
SetValue(CommandProperty, value);
}
}
public object CommandParameter
{
get
{
return GetValue(CommandParameterProperty);
}
set
{
SetValue(CommandParameterProperty, value);
}
}
public bool ScrollReset
{
get
{
return (bool)GetValue(ScrollResetProperty);
}
set
{
SetValue(ScrollResetProperty, value);
}
}
public bool IsLoading
{
get
{
return (bool)GetValue(IsLoadingProperty);
}
set
{
SetValue(IsLoadingProperty, value);
}
}
public Object LoadingContent
{
get
{
return GetValue(LoadingContentProperty);
}
set
{
SetValue(LoadingContentProperty, value);
}
}
protected override void OnScrollChanged(ScrollChangedEventArgs e)
{
base.OnScrollChanged(e);
if (VerticalOffset > 0)
{
//As User has moved Scroll Down So Scroll Is not More at its Reset Position Which is TOP
if (ScrollReset)
{
ScrollReset = false;
}
//Scroll movied to the end of the Page
if (VerticalOffset == ScrollableHeight)
{
if (Command != null)
{
//See if we can Exeute the Command
if (Command.CanExecute(CommandParameter))
{
try
{
//execute the Command
Command.Execute(CommandParameter);
}
catch (Exception)
{
Command.Execute(null);
}
}
}
}
}
}
}
}
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:po="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options"
xmlns:local="clr-namespace:InfiniteScrollViewerControl"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
>
<Border x:Key="loader" Margin="10" BorderThickness="3">
<StackPanel>
<TextBlock HorizontalAlignment="Center">Please Wait..</TextBlock>
<ProgressBar Height="10" IsIndeterminate="True" Orientation="Horizontal" />
</StackPanel>
</Border>
<Style TargetType="{x:Type local:InfiniteScrollViewer}">
<Setter Property="LoadingContent" Value="{StaticResource loader}"/>
<Setter Property="IsLoading" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:InfiniteScrollViewer}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ScrollContentPresenter />
<DockPanel Grid.Row="1" x:Name="loader" >
<ContentControl Content="{TemplateBinding LoadingContent}" />
</DockPanel>
</Grid>
<ScrollBar
Name="PART_VerticalScrollBar"
Opacity="0.75"
Grid.Column="1"
Value="{TemplateBinding VerticalOffset}"
Maximum="{TemplateBinding ScrollableHeight}"
ViewportSize="{TemplateBinding ViewportHeight}"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" />
<ScrollBar
Name="PART_HorizontalScrollBar"
Orientation="Horizontal"
Opacity="0.75"
Grid.Row="1"
Value="{TemplateBinding HorizontalOffset}"
Maximum="{TemplateBinding ScrollableWidth}"
ViewportSize="{TemplateBinding ViewportWidth}"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsLoading" Value="False">
<Setter TargetName="loader" Property="Visibility" Value="Collapsed"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment