diff --git a/Directory.Build.props b/Directory.Build.props
index 2109e5da730..c768621a4b1 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -21,7 +21,6 @@
$(MSBuildProjectName.Contains('Uwp'))
$(MSBuildProjectName.Contains('Sample'))
-
6.0.8
17134
14393
diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/PullToRefreshListView/PullToRefreshListViewPage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/PullToRefreshListView/PullToRefreshListViewPage.xaml.cs
index 684976e9b97..dee3d3477ac 100644
--- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/PullToRefreshListView/PullToRefreshListViewPage.xaml.cs
+++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/PullToRefreshListView/PullToRefreshListViewPage.xaml.cs
@@ -22,6 +22,7 @@ namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages
{
public sealed partial class PullToRefreshListViewPage : IXamlRenderListener
{
+#pragma warning disable CS0618
private readonly ObservableCollection- _items;
public PullToRefreshListViewPage()
@@ -50,5 +51,6 @@ private void ListView_RefreshCommand(object sender, EventArgs e)
{
AddItems();
}
+#pragma warning restore CS0618
}
}
diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/PullToRefreshListView/PullToRefreshListViewXaml.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/PullToRefreshListView/PullToRefreshListViewXaml.bind
index 6f548ab421e..a589ac65f8d 100644
--- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/PullToRefreshListView/PullToRefreshListViewXaml.bind
+++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/PullToRefreshListView/PullToRefreshListViewXaml.bind
@@ -16,7 +16,8 @@
Background="White"
OverscrollLimit="@[OverscrollLimit:DoubleSlider:0.4:0-1]"
PullThreshold="@[PullThreshold:Slider:100:50-300]"
- IsPullToRefreshWithMouseEnabled="@[IsPullToRefreshWithMouseEnabled:Bool:True]">
+ IsPullToRefreshWithMouseEnabled="@[IsPullToRefreshWithMouseEnabled:Bool:True]"
+ UseRefreshContainerWhenPossible="@[UseRefreshContainerWhenPossible:Bool:True]">
@@ -95,6 +97,17 @@ public class PullToRefreshListView : ListView
public static readonly DependencyProperty IsPullToRefreshWithMouseEnabledProperty =
DependencyProperty.Register(nameof(IsPullToRefreshWithMouseEnabled), typeof(bool), typeof(PullToRefreshListView), new PropertyMetadata(false));
+ ///
+ /// Identifies the dependency property
+ ///
+ public static readonly DependencyProperty UseRefreshContainerWhenPossibleProperty =
+ DependencyProperty.Register(nameof(UseRefreshContainerWhenPossible), typeof(bool), typeof(PullToRefreshListView), new PropertyMetadata(false, OnUseRefreshContainerWhenPossibleChanged));
+
+ ///
+ /// Gets a value indicating whether is supported
+ ///
+ public static bool IsRefreshContainerSupported { get; } = ApiInformation.IsTypePresent("Windows.UI.Xaml.Controls.RefreshContainer");
+
private const string PartRoot = "Root";
private const string PartScroller = "ScrollViewer";
private const string PartContentTransform = "ContentTransform";
@@ -103,6 +116,7 @@ public class PullToRefreshListView : ListView
private const string PartIndicatorTransform = "RefreshIndicatorTransform";
private const string PartDefaultIndicatorContent = "DefaultIndicatorContent";
private const string PullAndReleaseIndicatorContent = "PullAndReleaseIndicatorContent";
+ private const string PartRefreshContainer = "RefreshContainer";
private Border _root;
private Border _refreshIndicatorBorder;
@@ -123,6 +137,20 @@ public class PullToRefreshListView : ListView
private double _overscrollMultiplier;
private bool _isManipulatingWithMouse;
private double _startingVerticalOffset;
+ private ControlTemplate _previousTemplateUsed;
+ private RefreshContainer _refreshContainer;
+
+ private bool UsingRefreshContainer => IsRefreshContainerSupported && UseRefreshContainerWhenPossible;
+
+ ///
+ /// Gets or sets a value indicating whether the HamburgerMenu should use the NavigationView when possible (Fall Creators Update and above)
+ /// When set to true and the device supports NavigationView, the HamburgerMenu will use a template based on NavigationView
+ ///
+ public bool UseRefreshContainerWhenPossible
+ {
+ get { return (bool)GetValue(UseRefreshContainerWhenPossibleProperty); }
+ set { SetValue(UseRefreshContainerWhenPossibleProperty, value); }
+ }
///
/// Occurs when the user has requested content to be refreshed
@@ -185,6 +213,23 @@ protected override void OnApplyTemplate()
_root.ManipulationCompleted -= Scroller_ManipulationCompleted;
}
+ _root = null;
+ _refreshIndicatorBorder = null;
+ _refreshIndicatorTransform = null;
+ _scroller = null;
+ _contentTransform = null;
+ _headerTransform = null;
+ _footerTransform = null;
+ _scrollerContent = null;
+ _defaultIndicatorContent = null;
+ _pullAndReleaseIndicatorContent = null;
+ _scrollerVerticalScrollBar = null;
+
+ if (UsingRefreshContainer)
+ {
+ OnApplyRefreshContainerTemplate();
+ }
+
_root = GetTemplateChild(PartRoot) as Border;
_scroller = GetTemplateChild(PartScroller) as ScrollViewer;
_scrollerContent = GetTemplateChild(PartScrollerContent) as ItemsPresenter;
@@ -225,6 +270,21 @@ protected override void OnApplyTemplate()
base.OnApplyTemplate();
}
+ private void OnApplyRefreshContainerTemplate()
+ {
+ if (_refreshContainer != null)
+ {
+ _refreshContainer.RefreshRequested -= RefreshContainer_RefreshRequested;
+ }
+
+ _refreshContainer = GetTemplateChild(PartRefreshContainer) as RefreshContainer;
+
+ if (_refreshContainer != null)
+ {
+ _refreshContainer.RefreshRequested += RefreshContainer_RefreshRequested;
+ }
+ }
+
private void Scroller_ManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e)
{
// Other input are already managed by the scroll viewer
@@ -629,6 +689,18 @@ private void ScrollerVerticalScrollBar_PointerExited(object sender, PointerRoute
}
}
+ private void RefreshContainer_RefreshRequested(object sender, RefreshRequestedEventArgs args)
+ {
+ using (var deferral = args.GetDeferral())
+ {
+ RefreshRequested?.Invoke(this, EventArgs.Empty);
+ if (RefreshCommand != null && RefreshCommand.CanExecute(null))
+ {
+ RefreshCommand.Execute(null);
+ }
+ }
+ }
+
///
/// Gets or sets the Overscroll Limit. Value between 0 and 1 where 1 is the height of the control. Default is 0.3
///
@@ -663,6 +735,30 @@ private static void OnReleaseToRefreshLabelChanged(DependencyObject d, Dependenc
d.SetValue(ReleaseToRefreshLabelProperty, e.NewValue);
}
+ private static void OnUseRefreshContainerWhenPossibleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ var list = d as PullToRefreshListView;
+ if (list == null)
+ {
+ return;
+ }
+
+ if (list.UseRefreshContainerWhenPossible && IsRefreshContainerSupported)
+ {
+ ResourceDictionary dict = new ResourceDictionary();
+ dict.Source = new System.Uri("ms-appx:///Microsoft.Toolkit.Uwp.UI.Controls/PullToRefreshListView/PullToRefreshListViewRefreshContainerTemplate.xaml");
+ list._previousTemplateUsed = list.Template;
+ list.Template = dict["PullToRefreshListViewRefreshContainerTemplate"] as ControlTemplate;
+ }
+ else if (!list.UseRefreshContainerWhenPossible &&
+ e.OldValue is bool oldValue &&
+ oldValue &&
+ list._previousTemplateUsed != null)
+ {
+ list.Template = list._previousTemplateUsed;
+ }
+ }
+
///
/// Gets or sets the PullThreshold in pixels for when Refresh should be Requested. Default is 100
///
diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/PullToRefreshListView/PullToRefreshListView.xaml b/Microsoft.Toolkit.Uwp.UI.Controls/PullToRefreshListView/PullToRefreshListView.xaml
index bcffd1755a1..52db0058cff 100644
--- a/Microsoft.Toolkit.Uwp.UI.Controls/PullToRefreshListView/PullToRefreshListView.xaml
+++ b/Microsoft.Toolkit.Uwp.UI.Controls/PullToRefreshListView/PullToRefreshListView.xaml
@@ -2,6 +2,10 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Microsoft.Toolkit.Uwp.UI.Controls">
+
+
+
+
diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/PullToRefreshListView/PullToRefreshListViewRefreshContainerTemplate.xaml b/Microsoft.Toolkit.Uwp.UI.Controls/PullToRefreshListView/PullToRefreshListViewRefreshContainerTemplate.xaml
new file mode 100644
index 00000000000..0925675f32d
--- /dev/null
+++ b/Microsoft.Toolkit.Uwp.UI.Controls/PullToRefreshListView/PullToRefreshListViewRefreshContainerTemplate.xaml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Microsoft.Toolkit.Uwp.UI.Controls/PullToRefreshListView/PullToRefreshListViewTemplate.xaml b/Microsoft.Toolkit.Uwp.UI.Controls/PullToRefreshListView/PullToRefreshListViewTemplate.xaml
new file mode 100644
index 00000000000..562a6fa3337
--- /dev/null
+++ b/Microsoft.Toolkit.Uwp.UI.Controls/PullToRefreshListView/PullToRefreshListViewTemplate.xaml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/controls/PullToRefreshListview.md b/docs/controls/PullToRefreshListview.md
index 7e374bf4b59..632cd647ff1 100644
--- a/docs/controls/PullToRefreshListview.md
+++ b/docs/controls/PullToRefreshListview.md
@@ -7,7 +7,10 @@ keywords: windows 10, uwp, uwp community toolkit, uwp toolkit, PullToRefreshList
# PullToRefreshListView XAML Control
-The **PullToRefreshListView Control**, is derived from the built-in List View in XAML. It lets the user pull down beyond the top limit on the listview to trigger a refresh of the content. This control can create rich, animations, and is easy to use.
+> [!NOTE]
+The PullToRefreshListView is deprecated and will be removed in a future major release. Please use the [RefreshContainer](https://docs.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/pull-to-refresh) available in the 1803 version of Windows. Read the [Moving to RefreshContainer](#refreshcontainer) section for more info.
+
+The **PullToRefreshListView Control**, is derived from the built-in List View in XAML. It lets the user pull down beyond the top limit on the listview to trigger a refresh of the content. This control can create rich, animations, and is easy to use.
This control is very common on mobile devices, where the user can pull from the top to force a content refresh in applications like Twitter.
@@ -24,7 +27,7 @@ be raised and the *RefreshIntentCanceledCommand*, if any, will be executed.
```xaml
Moving to RefreshContainer
+The 1803 version of Windows now includes its own implementation of [pull-to-refresh](https://docs.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/pull-to-refresh) controls, having [RefreshContainer](https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.refreshcontainer) as the main control.
+
+The PullToRefreshListView and the RefreshContainer share the same concepts and provide mostly the same functionality, with the caveat that the RefreshContainer works only with a touch interface.
+
+### What developers need to know to move to RefreshContainer?
+
+* **XAML:** The RefreshContainer is very simple to use. Unlike the PullToRefreshListView, the RefreshContainer isn't based on the ListView control, so to use it you just need to add the XAML element as a parent of the element you'll use as your item container, like a ListView or a ScrollViewer.
+
+* **Code behind:** The RefreshContainer invokes the RefreshRequested event whenever a refresh is triggered. Unlike most event handlers, it has the peculiarity of coming with a [Deferral](https://docs.microsoft.com/en-us/uwp/api/windows.foundation.deferral) object, that you can get from the [RefreshRequestedEventArgs](https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.refreshrequestedeventargs) by calling [GetDeferral](https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.refreshrequestedeventargs.getdeferral#Windows_UI_Xaml_Controls_RefreshRequestedEventArgs_GetDeferral).
+To notify that your refresh code has completed, you can mark the deferral as completed by calling its Complete method or wrap your refresh code with a using statement of the deferral.
+
+> [!NOTE]
+Being a touch-only control, it's recommended that you also have a refresh button for users without a touch interface. You can trigger the RefreshRequested event by calling the RefreshContainer's RequestRefresh method.
+
+### Making the transition even easier
+Starting with v3.0 of the UWP Community Toolkit, the PullToRefreshListView provides a new property called **UseRefreshContainerWhenPossible**. Setting the value to true will force the PullToRefreshListView to use a template based on the RefreshContainer when running on the 1803 version of Windows and above, and the regular template otherwise.
+
+Using this property will enable you to take advantage of the RefreshContainer on devices that support it, while providing an experience based on PullToRefreshListView on devices that have not yet updated to the 1803 version of Windows. Make sure to test the experience on multiple OS releases and plan to fully transition to the RefreshContainer as the PullToRefreshListView will be removed from the UWP Community Toolkit in a future major release.
+
+> [!NOTE]
+When using the RefreshContainer, the RefreshIntentCanceled and the PullProgressChanged events are not invoked. In addition, the RefreshIntentCanceledCommand is not executed.
+
+There are several PullToRefreshListView properties that have no effect when the PullToRefreshListView is using the RefreshContainer:
+
+* OverscrollLimit
+* PullThreshold
+* RefreshIndicatorContent
+* PullToRefreshLabel
+* ReleaseToRefreshLabel
+* PullToRefreshContent
+* ReleaseToRefreshContent
+* IsPullToRefreshWithMouseEnabled
+
+
+## Default Template
[PullToRefreshListView XAML File](https://github.com/Microsoft/UWPCommunityToolkit/blob/master/Microsoft.Toolkit.Uwp.UI.Controls/PullToRefreshListView/PullToRefreshListView.xaml) is the XAML template used in the toolkit for the default styling.