diff --git a/src/Controls/samples/Controls.Sample/Pages/Controls/RefreshViewPage.xaml b/src/Controls/samples/Controls.Sample/Pages/Controls/RefreshViewPage.xaml index 77a24d79f581..522c075bb9f8 100644 --- a/src/Controls/samples/Controls.Sample/Pages/Controls/RefreshViewPage.xaml +++ b/src/Controls/samples/Controls.Sample/Pages/Controls/RefreshViewPage.xaml @@ -28,22 +28,18 @@ - - + + @@ -52,36 +48,28 @@ - + - + - + - - - - - + BindableLayout.ItemTemplate="{StaticResource ColorItemTemplate}" /> + - - \ No newline at end of file diff --git a/src/Controls/samples/Controls.Sample/ViewModels/RefreshViewModel.cs b/src/Controls/samples/Controls.Sample/ViewModels/RefreshViewModel.cs index 635c1e6f52b2..35653f66e688 100644 --- a/src/Controls/samples/Controls.Sample/ViewModels/RefreshViewModel.cs +++ b/src/Controls/samples/Controls.Sample/ViewModels/RefreshViewModel.cs @@ -57,7 +57,7 @@ void AddItems() { Items.Add(new RefreshItem { - Color = Color.FromRgb(_random.Next(0, 255), _random.Next(0, 255), _random.Next(0, 255)), + Color = Color.FromRgb(_random.NextDouble(), _random.NextDouble(), _random.NextDouble()), Name = $"Item {_itemNumber++}" }); } diff --git a/src/Controls/src/Core/Hosting/AppHostBuilderExtensions.cs b/src/Controls/src/Core/Hosting/AppHostBuilderExtensions.cs index 587674c9c2e8..7c4319efe0a6 100644 --- a/src/Controls/src/Core/Hosting/AppHostBuilderExtensions.cs +++ b/src/Controls/src/Core/Hosting/AppHostBuilderExtensions.cs @@ -51,6 +51,7 @@ public static IMauiHandlersCollection AddMauiControlsHandlers(this IMauiHandlers handlersCollection.AddHandler(); handlersCollection.AddHandler(); handlersCollection.AddHandler(); + handlersCollection.AddHandler(); handlersCollection.AddHandler(); handlersCollection.AddHandler(); @@ -60,7 +61,6 @@ public static IMauiHandlersCollection AddMauiControlsHandlers(this IMauiHandlers handlersCollection.AddHandler(); #if ANDROID || IOS - handlersCollection.AddHandler(); handlersCollection.AddHandler(); #endif #if WINDOWS || ANDROID diff --git a/src/Core/src/Handlers/RefreshView/RefreshViewHandler.Windows.cs b/src/Core/src/Handlers/RefreshView/RefreshViewHandler.Windows.cs index 460cf7dcba89..433fc9d829c3 100644 --- a/src/Core/src/Handlers/RefreshView/RefreshViewHandler.Windows.cs +++ b/src/Core/src/Handlers/RefreshView/RefreshViewHandler.Windows.cs @@ -1,35 +1,127 @@ -using System; -using System.Collections.Generic; -using System.Text; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Maui.Dispatching; +using Microsoft.Maui.Graphics; using Microsoft.UI.Xaml.Controls; +using Windows.Foundation; +using WBrush = Microsoft.UI.Xaml.Media.Brush; namespace Microsoft.Maui.Handlers { public partial class RefreshViewHandler : ViewHandler { + bool _isLoaded; + Deferral? _refreshCompletionDeferral; + protected override RefreshContainer CreatePlatformView() { - return new RefreshContainer(); + return new RefreshContainer + { + PullDirection = RefreshPullDirection.TopToBottom + }; } - [MissingMapper] - public static void MapIsRefreshing(IRefreshViewHandler handler, IRefreshView refreshView) + protected override void ConnectHandler(RefreshContainer nativeView) { + nativeView.Loaded += OnLoaded; + nativeView.RefreshRequested += OnRefresh; + + base.ConnectHandler(nativeView); } - [MissingMapper] - public static void MapContent(IRefreshViewHandler handler, IRefreshView refreshView) + protected override void DisconnectHandler(RefreshContainer nativeView) { + nativeView.Loaded -= OnLoaded; + nativeView.RefreshRequested -= OnRefresh; + + CompleteRefresh(); + + base.DisconnectHandler(nativeView); } - [MissingMapper] + public static void MapIsRefreshing(IRefreshViewHandler handler, IRefreshView refreshView) + => (handler as RefreshViewHandler)?.UpdateIsRefreshing(); + + public static void MapContent(IRefreshViewHandler handler, IRefreshView refreshView) + => UpdateContent(handler); + public static void MapRefreshColor(IRefreshViewHandler handler, IRefreshView refreshView) + => UpdateRefreshColor(handler); + + public static void MapRefreshViewBackground(IRefreshViewHandler handler, IView view) + => UpdateBackground(handler); + + void UpdateIsRefreshing() { + if (!_isLoaded) + return; + + if (!VirtualView?.IsRefreshing ?? false) + CompleteRefresh(); + else if (_refreshCompletionDeferral == null) + PlatformView?.RequestRefresh(); } - [MissingMapper] - public static void MapRefreshViewBackground(IRefreshViewHandler handler, IView view) + static void UpdateContent(IRefreshViewHandler handler) + { + handler.PlatformView.Content = + handler.VirtualView.Content.ToPlatform(handler.MauiContext!); + } + + static void UpdateRefreshColor(IRefreshViewHandler handler) + { + if (handler.VirtualView == null || handler.PlatformView?.Visualizer == null) + return; + + handler.PlatformView.Visualizer.Foreground = handler.VirtualView.RefreshColor != null + ? handler.VirtualView.RefreshColor.ToPlatform() + : (WBrush)UI.Xaml.Application.Current.Resources["DefaultTextForegroundThemeBrush"]; + } + + static void UpdateBackground(IRefreshViewHandler handler) + { + if (handler.PlatformView?.Visualizer == null) + return; + + if (handler.VirtualView.Background != null) + handler.PlatformView.Visualizer.Background = handler.VirtualView.Background.ToPlatform(); + } + + // Telling the refresh to start before the control has been sized + // causes no refresh circle to show up + void OnLoaded(object sender, object args) + { + var refreshControl = sender as RefreshContainer; + + if (refreshControl == null || MauiContext == null) + return; + + refreshControl.Loaded -= OnLoaded; + MauiContext.Services + .GetRequiredService() + .Dispatch(() => + { + _isLoaded = true; + UpdateIsRefreshing(); + }); + } + + void OnRefresh(object sender, RefreshRequestedEventArgs args) + { + CompleteRefresh(); + _refreshCompletionDeferral = args.GetDeferral(); + + if (VirtualView != null) + VirtualView.IsRefreshing = true; + } + + void CompleteRefresh() { + if (_refreshCompletionDeferral != null) + { + _refreshCompletionDeferral.Complete(); + _refreshCompletionDeferral.Dispose(); + _refreshCompletionDeferral = null; + } } } } diff --git a/src/Core/src/Handlers/RefreshView/RefreshViewHandler.iOS.cs b/src/Core/src/Handlers/RefreshView/RefreshViewHandler.iOS.cs index 11993acc6e78..7c5cff762a1a 100644 --- a/src/Core/src/Handlers/RefreshView/RefreshViewHandler.iOS.cs +++ b/src/Core/src/Handlers/RefreshView/RefreshViewHandler.iOS.cs @@ -17,12 +17,14 @@ protected override MauiRefreshView CreatePlatformView() protected override void ConnectHandler(MauiRefreshView platformView) { platformView.RefreshControl.ValueChanged += OnRefresh; + base.ConnectHandler(platformView); } protected override void DisconnectHandler(MauiRefreshView platformView) { platformView.RefreshControl.ValueChanged -= OnRefresh; + base.DisconnectHandler(platformView); } @@ -61,6 +63,5 @@ static void UpdateRefreshColor(IRefreshViewHandler handler) if (color != null) handler.PlatformView.RefreshControl.TintColor = color; } - } }