diff --git a/NuGet.config b/NuGet.config index 7928751c3b3f..c9f489a210d2 100644 --- a/NuGet.config +++ b/NuGet.config @@ -1,4 +1,4 @@ - + diff --git a/src/Compatibility/Core/src/Android/AppCompat/Platform.cs b/src/Compatibility/Core/src/Android/AppCompat/Platform.cs index c9cdc3f0aa2f..e7366697c58d 100644 --- a/src/Compatibility/Core/src/Android/AppCompat/Platform.cs +++ b/src/Compatibility/Core/src/Android/AppCompat/Platform.cs @@ -7,6 +7,7 @@ using Android.OS; using Android.Views; using Android.Views.Animations; +using CommunityToolkit.Mvvm.Messaging; using Microsoft.Maui.Controls.Internals; using Microsoft.Maui.Controls.Platform; using Microsoft.Maui.Graphics; @@ -27,8 +28,6 @@ public class Platform : BindableObject, IPlatformLayout, INavigation internal static string PackageName { get; private set; } internal static string GetPackageName() => PackageName; - internal const string CloseContextActionsSignalName = "Xamarin.CloseContextActions"; - internal static readonly BindableProperty RendererProperty = BindableProperty.CreateAttached("Renderer", typeof(IVisualElementRenderer), typeof(Platform), default(IVisualElementRenderer), propertyChanged: (bindable, oldvalue, newvalue) => { @@ -81,7 +80,7 @@ internal bool NavAnimationInProgress return; _navAnimationInProgress = value; if (value) - MessagingCenter.Send(this, CloseContextActionsSignalName); + WeakReferenceMessenger.Default.Send(new CloseContextActionsMessage()); } } diff --git a/src/Compatibility/Core/src/Android/PopupManager.cs b/src/Compatibility/Core/src/Android/PopupManager.cs index 499fc479956a..bcdab131d088 100644 --- a/src/Compatibility/Core/src/Android/PopupManager.cs +++ b/src/Compatibility/Core/src/Android/PopupManager.cs @@ -6,6 +6,7 @@ using Android.Text; using Android.Views; using Android.Widget; +using CommunityToolkit.Mvvm.Messaging; using Microsoft.Maui.Controls.Internals; using AppCompatActivity = AndroidX.AppCompat.App.AppCompatActivity; using AppCompatAlertDialog = AndroidX.AppCompat.App.AlertDialog; @@ -50,20 +51,18 @@ internal sealed class PopupRequestHelper : IDisposable internal PopupRequestHelper(Activity context) { Activity = context; - MessagingCenter.Subscribe(Activity, Page.BusySetSignalName, OnPageBusy); - MessagingCenter.Subscribe(Activity, Page.AlertSignalName, OnAlertRequested); - MessagingCenter.Subscribe(Activity, Page.PromptSignalName, OnPromptRequested); - MessagingCenter.Subscribe(Activity, Page.ActionSheetSignalName, OnActionSheetRequested); + + WeakReferenceMessenger.Default.Register(this, static (r, m) => r.OnPageBusy(m.Page, m.IsBusy)); + WeakReferenceMessenger.Default.Register(this, static (r, m) => r.OnAlertRequested(m.Page, m.Arguments)); + WeakReferenceMessenger.Default.Register(this, static (r, m) => r.OnPromptRequested(m.Page, m.Arguments)); + WeakReferenceMessenger.Default.Register(this, static (r, m) => r.OnActionSheetRequested(m.Page, m.Arguments)); } public Activity Activity { get; } public void Dispose() { - MessagingCenter.Unsubscribe(Activity, Page.BusySetSignalName); - MessagingCenter.Unsubscribe(Activity, Page.AlertSignalName); - MessagingCenter.Unsubscribe(Activity, Page.PromptSignalName); - MessagingCenter.Unsubscribe(Activity, Page.ActionSheetSignalName); + WeakReferenceMessenger.Default.UnregisterAll(this); } public void ResetBusyCount() diff --git a/src/Compatibility/Core/src/Android/Renderers/ListViewAdapter.cs b/src/Compatibility/Core/src/Android/Renderers/ListViewAdapter.cs index 4e317dbf05d6..7b9ff6f4c7c7 100644 --- a/src/Compatibility/Core/src/Android/Renderers/ListViewAdapter.cs +++ b/src/Compatibility/Core/src/Android/Renderers/ListViewAdapter.cs @@ -7,6 +7,7 @@ using Android.Util; using Android.Views; using Android.Widget; +using CommunityToolkit.Mvvm.Messaging; using Microsoft.Maui.Controls.Internals; using Microsoft.Maui.Graphics; using AListView = Android.Widget.ListView; @@ -64,7 +65,7 @@ public ListViewAdapter(Context context, AListView realListView, ListView listVie realListView.OnItemClickListener = this; realListView.OnItemLongClickListener = this; - MessagingCenter.Subscribe(this, Platform.CloseContextActionsSignalName, lva => CloseContextActions()); + WeakReferenceMessenger.Default.Register(this, static (r, m) => r.CloseContextActions()); InvalidateCount(); } @@ -436,7 +437,7 @@ protected override void Dispose(bool disposing) { CloseContextActions(); - MessagingCenter.Unsubscribe(this, Platform.CloseContextActionsSignalName); + WeakReferenceMessenger.Default.Unregister(this); _realListView.OnItemClickListener = null; _realListView.OnItemLongClickListener = null; diff --git a/src/Compatibility/Core/src/Windows/Platform.cs b/src/Compatibility/Core/src/Windows/Platform.cs index 277f70d339fb..c2e010c535ca 100644 --- a/src/Compatibility/Core/src/Windows/Platform.cs +++ b/src/Compatibility/Core/src/Windows/Platform.cs @@ -14,6 +14,7 @@ using Microsoft.Maui.Controls.Platform; using WVisibility = Microsoft.UI.Xaml.Visibility; using Microsoft.Extensions.Logging; +using CommunityToolkit.Mvvm.Messaging; namespace Microsoft.Maui.Controls.Compatibility.Platform.UWP { @@ -136,10 +137,10 @@ internal Platform(Microsoft.UI.Xaml.Window page) _container.SizeChanged += OnRendererSizeChanged; - MessagingCenter.Subscribe(this, Page.BusySetSignalName, (Page sender, bool enabled) => + WeakReferenceMessenger.Default.Register(page, (_, message) => { Microsoft.UI.Xaml.Controls.ProgressBar indicator = GetBusyIndicator(); - indicator.Visibility = enabled ? WVisibility.Visible : WVisibility.Collapsed; + indicator.Visibility = message.IsBusy ? WVisibility.Visible : WVisibility.Collapsed; }); _toolbarTracker.CollectionChanged += OnToolbarItemsChanged; @@ -601,13 +602,16 @@ internal IToolbarProvider GetToolbarProvider() internal static void SubscribeAlertsAndActionSheets() { - MessagingCenter.Subscribe(Forms.MainWindow, Page.AlertSignalName, OnPageAlert); - MessagingCenter.Subscribe(Forms.MainWindow, Page.ActionSheetSignalName, OnPageActionSheet); - MessagingCenter.Subscribe(Forms.MainWindow, Page.PromptSignalName, OnPagePrompt); + WeakReferenceMessenger.Default.Register(Forms.MainWindow, (r,m) => OnPageAlert(m)); + WeakReferenceMessenger.Default.Register(Forms.MainWindow, (r, m) => OnPagePrompt(m)); + WeakReferenceMessenger.Default.Register(Forms.MainWindow, (r, m) => OnPageActionSheet(m)); } - static void OnPageActionSheet(Page sender, ActionSheetArguments options) + static void OnPageActionSheet(ActionSheetMessage message) { + var sender = message.Page; + var options = message.Arguments; + bool userDidSelect = false; if (options.FlowDirection == FlowDirection.MatchParent) @@ -654,8 +658,11 @@ static void OnPageActionSheet(Page sender, ActionSheetArguments options) } } - static async void OnPagePrompt(Page sender, PromptArguments options) + static async void OnPagePrompt(PromptMessage message) { + var sender = message.Page; + var options = message.Arguments; + var promptDialog = new PromptDialog { Title = options.Title ?? string.Empty, @@ -693,8 +700,11 @@ static async Task ShowPrompt(PromptDialog prompt) return null; } - static async void OnPageAlert(Page sender, AlertArguments options) + static async void OnPageAlert(PageAlertMessage message) { + var sender = message.Page; + var options = message.Arguments; + string content = options.Message ?? string.Empty; string title = options.Title ?? string.Empty; diff --git a/src/Compatibility/Core/src/iOS/Platform.cs b/src/Compatibility/Core/src/iOS/Platform.cs index 486ec1b4d83b..971f0636348d 100644 --- a/src/Compatibility/Core/src/iOS/Platform.cs +++ b/src/Compatibility/Core/src/iOS/Platform.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using CommunityToolkit.Mvvm.Messaging; using CoreGraphics; using Foundation; using Microsoft.Extensions.Logging; @@ -655,30 +656,43 @@ internal static string ResolveMsAppDataUri(Uri uri) internal void SubscribeToAlertsAndActionSheets() { var busyCount = 0; - MessagingCenter.Subscribe(this, Page.BusySetSignalName, (Page sender, bool enabled) => + + WeakReferenceMessenger.Default.Register(this, (platform, message) => { + var sender = message.Page; + var enabled = message.IsBusy; + if (!PageIsChildOfPlatform(sender)) return; busyCount = Math.Max(0, enabled ? busyCount + 1 : busyCount - 1); UIApplication.SharedApplication.NetworkActivityIndicatorVisible = busyCount > 0; }); - MessagingCenter.Subscribe(this, Page.AlertSignalName, (Page sender, AlertArguments arguments) => + WeakReferenceMessenger.Default.Register(this, (platform, message) => { + var sender = message.Page; + var arguments = message.Arguments; + if (!PageIsChildOfPlatform(sender)) return; PresentAlert(arguments); }); - MessagingCenter.Subscribe(this, Page.PromptSignalName, (Page sender, PromptArguments arguments) => + WeakReferenceMessenger.Default.Register(this, (platform, message) => { + var sender = message.Page; + var arguments = message.Arguments; + if (!PageIsChildOfPlatform(sender)) return; PresentPrompt(arguments); }); - MessagingCenter.Subscribe(this, Page.ActionSheetSignalName, (Page sender, ActionSheetArguments arguments) => + WeakReferenceMessenger.Default.Register(this, (platform, message) => { + var sender = message.Page; + var arguments = message.Arguments; + if (!PageIsChildOfPlatform(sender)) return; @@ -695,10 +709,6 @@ static bool IsModalPresentedFullScreen(Page modal) internal void UnsubscribeFromAlertsAndActionsSheets() { - MessagingCenter.Unsubscribe(this, Page.ActionSheetSignalName); - MessagingCenter.Unsubscribe(this, Page.AlertSignalName); - MessagingCenter.Unsubscribe(this, Page.PromptSignalName); - MessagingCenter.Unsubscribe(this, Page.BusySetSignalName); } internal void MarkForRemoval() diff --git a/src/Compatibility/Core/src/iOS/Renderers/NavigationRenderer.cs b/src/Compatibility/Core/src/iOS/Renderers/NavigationRenderer.cs index 8f767d141c84..3ee8f8bb7461 100644 --- a/src/Compatibility/Core/src/iOS/Renderers/NavigationRenderer.cs +++ b/src/Compatibility/Core/src/iOS/Renderers/NavigationRenderer.cs @@ -17,12 +17,12 @@ using PointF = CoreGraphics.CGPoint; using RectangleF = CoreGraphics.CGRect; using SizeF = CoreGraphics.CGSize; +using CommunityToolkit.Mvvm.Messaging; namespace Microsoft.Maui.Controls.Compatibility.Platform.iOS { public class NavigationRenderer : UINavigationController, IVisualElementRenderer, IEffectControlProvider { - internal const string UpdateToolbarButtons = "Xamarin.UpdateToolbarButtons"; bool _appeared; bool _ignorePopCall; bool _loaded; @@ -40,11 +40,11 @@ public class NavigationRenderer : UINavigationController, IVisualElementRenderer [Preserve(Conditional = true)] public NavigationRenderer() : base(typeof(FormsNavigationBar), null) { - MessagingCenter.Subscribe(this, UpdateToolbarButtons, sender => + WeakReferenceMessenger.Default.Register(this, static (receiver, message) => { - if (!ViewControllers.Any()) + if (!receiver.ViewControllers.Any()) return; - var parentingViewController = GetParentingViewController(); + var parentingViewController = receiver.GetParentingViewController(); parentingViewController?.UpdateLeftBarButtonItem(); }); } @@ -262,7 +262,7 @@ protected override void Dispose(bool disposing) if (disposing) { - MessagingCenter.Unsubscribe(this, UpdateToolbarButtons); + WeakReferenceMessenger.Default.Unregister(this); foreach (var childViewController in ViewControllers) childViewController.Dispose(); @@ -1711,4 +1711,6 @@ protected override void Dispose(bool disposing) } } } + + internal sealed class UpdateToolBarButtonsMessage { } } diff --git a/src/Compatibility/Core/src/iOS/Renderers/TabletFlyoutPageRenderer.cs b/src/Compatibility/Core/src/iOS/Renderers/TabletFlyoutPageRenderer.cs index 10e3cd8bffe3..c33b6580ac48 100644 --- a/src/Compatibility/Core/src/iOS/Renderers/TabletFlyoutPageRenderer.cs +++ b/src/Compatibility/Core/src/iOS/Renderers/TabletFlyoutPageRenderer.cs @@ -6,6 +6,7 @@ using Microsoft.Maui.Graphics; using ObjCRuntime; using UIKit; +using CommunityToolkit.Mvvm.Messaging; namespace Microsoft.Maui.Controls.Compatibility.Platform.iOS { @@ -391,7 +392,8 @@ public override void WillRotate(UIInterfaceOrientation toInterfaceOrientation, d } FlyoutPage.UpdateFlyoutLayoutBehavior(); - MessagingCenter.Send(this, NavigationRenderer.UpdateToolbarButtons); + + WeakReferenceMessenger.Default.Send(new UpdateToolBarButtonsMessage()); } base.WillRotate(toInterfaceOrientation, duration); @@ -449,7 +451,7 @@ void ClearControllers() void HandleFlyoutPropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == Page.IconImageSourceProperty.PropertyName || e.PropertyName == Page.TitleProperty.PropertyName) - MessagingCenter.Send(this, NavigationRenderer.UpdateToolbarButtons); + WeakReferenceMessenger.Default.Send(new UpdateToolBarButtonsMessage()); } void HandlePropertyChanged(object sender, PropertyChangedEventArgs e) @@ -470,7 +472,7 @@ void HandlePropertyChanged(object sender, PropertyChangedEventArgs e) else if (e.Is(Microsoft.Maui.Controls.FlyoutPage.FlyoutLayoutBehaviorProperty)) UpdateFlyoutLayoutBehavior(base.View.Bounds.Size); - MessagingCenter.Send(this, NavigationRenderer.UpdateToolbarButtons); + WeakReferenceMessenger.Default.Send(new UpdateToolBarButtonsMessage()); } public override void ViewWillTransitionToSize(CGSize toSize, IUIViewControllerTransitionCoordinator coordinator) diff --git a/src/Compatibility/Maps/src/Android/MapRenderer.cs b/src/Compatibility/Maps/src/Android/MapRenderer.cs index c4429269f684..8b6b14073c65 100644 --- a/src/Compatibility/Maps/src/Android/MapRenderer.cs +++ b/src/Compatibility/Maps/src/Android/MapRenderer.cs @@ -27,13 +27,12 @@ using Math = System.Math; using Polygon = Microsoft.Maui.Controls.Maps.Polygon; using Polyline = Microsoft.Maui.Controls.Maps.Polyline; +using CommunityToolkit.Mvvm.Messaging; namespace Microsoft.Maui.Controls.Compatibility.Maps.Android { public class MapRenderer : ViewRenderer, GoogleMap.IOnCameraMoveListener, IOnMapReadyCallback { - const string MoveMessageName = "MapMoveToRegion"; - static Bundle s_bundle; bool _disposed; @@ -82,8 +81,8 @@ protected override void Dispose(bool disposing) { if (Element != null) { - MessagingCenter.Unsubscribe(this, MoveMessageName); - + WeakReferenceMessenger.Default.Unregister(this); + ((ObservableCollection)Element.Pins).CollectionChanged -= OnPinCollectionChanged; foreach (Pin pin in Element.Pins) { @@ -142,7 +141,7 @@ protected override void OnElementChanged(ElementChangedEventArgs e) child.PropertyChanged -= MapElementPropertyChanged; } - MessagingCenter.Unsubscribe(this, MoveMessageName); + WeakReferenceMessenger.Default.Unregister(this); if (NativeMap != null) { @@ -158,7 +157,7 @@ protected override void OnElementChanged(ElementChangedEventArgs e) Control.GetMapAsync(this); - MessagingCenter.Subscribe(this, MoveMessageName, OnMoveToRegionMessage, Map); + WeakReferenceMessenger.Default.Register(this, static (r, m) => r.OnMoveToRegionMessage(r.Element, m)); ((INotifyCollectionChanged)Map.Pins).CollectionChanged += OnPinCollectionChanged; ((INotifyCollectionChanged)Map.MapElements).CollectionChanged += OnMapElementCollectionChanged; diff --git a/src/Compatibility/Maps/src/iOS/MapRenderer.cs b/src/Compatibility/Maps/src/iOS/MapRenderer.cs index fc0d8d527145..ed8f874c9be2 100644 --- a/src/Compatibility/Maps/src/iOS/MapRenderer.cs +++ b/src/Compatibility/Maps/src/iOS/MapRenderer.cs @@ -11,6 +11,7 @@ using Microsoft.Maui.Controls.Maps; using Microsoft.Maui.Graphics; using Microsoft.Maui.Controls.Platform; +using CommunityToolkit.Mvvm.Messaging; #if __MOBILE__ using UIKit; @@ -34,8 +35,6 @@ public class MapRenderer : ViewRenderer UITapGestureRecognizer _mapClickedGestureRecognizer; #endif - const string MoveMessageName = "MapMoveToRegion"; - public override SizeRequest GetDesiredSize(double widthConstraint, double heightConstraint) { return Control.GetSizeRequest(widthConstraint, heightConstraint); @@ -64,7 +63,7 @@ protected override void Dispose(bool disposing) if (Element != null) { var mapModel = (Map)Element; - MessagingCenter.Unsubscribe(this, MoveMessageName); + WeakReferenceMessenger.Default.Unregister(this); ((ObservableCollection)mapModel.Pins).CollectionChanged -= OnPinCollectionChanged; ((ObservableCollection)mapModel.MapElements).CollectionChanged -= OnMapElementCollectionChanged; foreach (Pin pin in mapModel.Pins) @@ -118,7 +117,7 @@ protected override void OnElementChanged(ElementChangedEventArgs e) { var mapModel = (Map)e.OldElement; - MessagingCenter.Unsubscribe(this, MoveMessageName); + WeakReferenceMessenger.Default.Unregister(this); ((ObservableCollection)mapModel.Pins).CollectionChanged -= OnPinCollectionChanged; foreach (Pin pin in mapModel.Pins) @@ -165,7 +164,8 @@ protected override void OnElementChanged(ElementChangedEventArgs e) #endif } - MessagingCenter.Subscribe(this, MoveMessageName, (s, a) => MoveToRegion(a), mapModel); + WeakReferenceMessenger.Default.Register(this, static (r, m) => r.MoveToRegion(m)); + if (mapModel.LastMoveToRegion != null) MoveToRegion(mapModel.LastMoveToRegion, false); diff --git a/src/Controls/Maps/src/Map.cs b/src/Controls/Maps/src/Map.cs index f5d0065828fc..f4a73dd0f55c 100644 --- a/src/Controls/Maps/src/Map.cs +++ b/src/Controls/Maps/src/Map.cs @@ -5,6 +5,7 @@ using System.Collections.Specialized; using System.ComponentModel; using System.Linq; +using CommunityToolkit.Mvvm.Messaging; using Microsoft.Maui.Controls.Internals; namespace Microsoft.Maui.Controls.Maps @@ -153,7 +154,8 @@ public void MoveToRegion(MapSpan mapSpan) if (mapSpan == null) throw new ArgumentNullException(nameof(mapSpan)); LastMoveToRegion = mapSpan; - MessagingCenter.Send(this, "MapMoveToRegion", mapSpan); + + WeakReferenceMessenger.Default.Send(mapSpan); } void PinsOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) diff --git a/src/Controls/src/Core/Controls.Core-net6.csproj b/src/Controls/src/Core/Controls.Core-net6.csproj index 75d5d3b9b772..71d0b60e8b56 100644 --- a/src/Controls/src/Core/Controls.Core-net6.csproj +++ b/src/Controls/src/Core/Controls.Core-net6.csproj @@ -22,6 +22,7 @@ + diff --git a/src/Controls/src/Core/HandlerImpl/Page.Impl.cs b/src/Controls/src/Core/HandlerImpl/Page.Impl.cs index bfaba777c8ad..a8678fafbe9a 100644 --- a/src/Controls/src/Core/HandlerImpl/Page.Impl.cs +++ b/src/Controls/src/Core/HandlerImpl/Page.Impl.cs @@ -79,4 +79,6 @@ internal NavigatedFromEventArgs(Page destinationPage) internal Page DestinationPage { get; } } + + public sealed class CloseContextActionsMessage { } } diff --git a/src/Controls/src/Core/IsExternalInit.cs b/src/Controls/src/Core/IsExternalInit.cs new file mode 100644 index 000000000000..49c7c9430e3d --- /dev/null +++ b/src/Controls/src/Core/IsExternalInit.cs @@ -0,0 +1,9 @@ +// https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.isexternalinit?view=net-5.0 +// https://developercommunity.visualstudio.com/t/error-cs0518-predefined-type-systemruntimecompiler/1244809 +// Adding this because at least one of the target frameworks doesn't include it; hopefully we can drop this at some point +// (and hopefully before release) +// TODO ezhart Evaluate whether we still need this +namespace System.Runtime.CompilerServices +{ + internal static class IsExternalInit { } +} diff --git a/src/Controls/src/Core/Page.cs b/src/Controls/src/Core/Page.cs index e1de047a55d3..2b375c4e24fa 100644 --- a/src/Controls/src/Core/Page.cs +++ b/src/Controls/src/Core/Page.cs @@ -4,24 +4,16 @@ using System.Collections.Specialized; using System.ComponentModel; using System.Linq; -using System.Threading; using System.Threading.Tasks; using Microsoft.Maui.Controls.Internals; using Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific; using Microsoft.Maui.Graphics; +using CommunityToolkit.Mvvm.Messaging; namespace Microsoft.Maui.Controls { public partial class Page : VisualElement, ILayout, IPageController, IElementConfiguration, IPaddingElement, ISafeAreaView { - public const string BusySetSignalName = "Microsoft.Maui.Controls.BusySet"; - - public const string AlertSignalName = "Microsoft.Maui.Controls.SendAlert"; - - public const string PromptSignalName = "Microsoft.Maui.Controls.SendPrompt"; - - public const string ActionSheetSignalName = "Microsoft.Maui.Controls.ShowActionSheet"; - internal static readonly BindableProperty IgnoresContainerAreaProperty = BindableProperty.Create("IgnoresContainerArea", typeof(bool), typeof(Page), false); public static readonly BindableProperty BackgroundImageSourceProperty = BindableProperty.Create(nameof(BackgroundImageSource), typeof(ImageSource), typeof(Page), default(ImageSource)); @@ -168,9 +160,13 @@ public Task DisplayActionSheet(string title, string cancel, string destr args.FlowDirection = flowDirection; if (IsPlatformEnabled) - MessagingCenter.Send(this, ActionSheetSignalName, args); + { + WeakReferenceMessenger.Default.Send(new ActionSheetMessage(this, args)); + } else - _pendingActions.Add(() => MessagingCenter.Send(this, ActionSheetSignalName, args)); + { + _pendingActions.Add(() => WeakReferenceMessenger.Default.Send(new ActionSheetMessage(this, args))); + } return args.Result.Task; } @@ -199,9 +195,13 @@ public Task DisplayAlert(string title, string message, string accept, stri args.FlowDirection = flowDirection; if (IsPlatformEnabled) - MessagingCenter.Send(this, AlertSignalName, args); + { + WeakReferenceMessenger.Default.Send(new PageAlertMessage(this, args)); + } else - _pendingActions.Add(() => MessagingCenter.Send(this, AlertSignalName, args)); + { + _pendingActions.Add(() => WeakReferenceMessenger.Default.Send(new PageAlertMessage(this, args))); + } return args.Result.Task; } @@ -211,9 +211,13 @@ public Task DisplayAlert(string title, string message, string accept, stri var args = new PromptArguments(title, message, accept, cancel, placeholder, maxLength, keyboard, initialValue); if (IsPlatformEnabled) - MessagingCenter.Send(this, PromptSignalName, args); + { + WeakReferenceMessenger.Default.Send(new PromptMessage(this, args)); + } else - _pendingActions.Add(() => MessagingCenter.Send(this, PromptSignalName, args)); + { + _pendingActions.Add(() => WeakReferenceMessenger.Default.Send(new PromptMessage(this, args))); + } return args.Result.Task; } @@ -430,9 +434,13 @@ public void SendAppearing() if (IsBusy) { if (IsPlatformEnabled) - MessagingCenter.Send(this, BusySetSignalName, true); + { + WeakReferenceMessenger.Default.Send(new PageBusyMessage(this, true)); + } else - _pendingActions.Add(() => MessagingCenter.Send(this, BusySetSignalName, true)); + { + _pendingActions.Add(() => WeakReferenceMessenger.Default.Send(new PageBusyMessage(this, true))); + } } OnAppearing(); @@ -453,7 +461,9 @@ public void SendDisappearing() _hasAppeared = false; if (IsBusy) - MessagingCenter.Send(this, BusySetSignalName, false); + { + WeakReferenceMessenger.Default.Send(new PageBusyMessage(this, false)); + } var pageContainer = this as IPageContainer; pageContainer?.CurrentPage?.SendDisappearing(); @@ -510,7 +520,7 @@ void OnPageBusyChanged() if (!_hasAppeared) return; - MessagingCenter.Send(this, BusySetSignalName, IsBusy); + WeakReferenceMessenger.Default.Send(new PageBusyMessage(this, IsBusy)); } void OnToolbarItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs args) @@ -564,4 +574,14 @@ internal void SetTitleView(View oldTitleView, View newTitleView) _titleView = newTitleView; } } + + // TODO ezhart These Pages could probably all be IView + public sealed record PageBusyMessage(Page Page, bool IsBusy); + + public sealed record PageAlertMessage(Page Page, AlertArguments Arguments); + + public sealed record PromptMessage(Page Page, PromptArguments Arguments); + + public sealed record ActionSheetMessage(Page Page, ActionSheetArguments Arguments); } + diff --git a/src/Controls/src/Core/Platform/AlertManager/AlertManager.Android.cs b/src/Controls/src/Core/Platform/AlertManager/AlertManager.Android.cs index 1b41260ba404..4e9ca672272b 100644 --- a/src/Controls/src/Core/Platform/AlertManager/AlertManager.Android.cs +++ b/src/Controls/src/Core/Platform/AlertManager/AlertManager.Android.cs @@ -7,6 +7,7 @@ using Android.Text; using Android.Views; using Android.Widget; +using CommunityToolkit.Mvvm.Messaging; using Microsoft.Maui.Controls.Internals; using AButton = Android.Widget.Button; using AppCompatActivity = AndroidX.AppCompat.App.AppCompatActivity; @@ -64,10 +65,10 @@ internal AlertRequestHelper(Activity context, IMauiContext mauiContext) Activity = context; MauiContext = mauiContext; - MessagingCenter.Subscribe(Activity, Page.BusySetSignalName, OnPageBusy); - MessagingCenter.Subscribe(Activity, Page.AlertSignalName, OnAlertRequested); - MessagingCenter.Subscribe(Activity, Page.PromptSignalName, OnPromptRequested); - MessagingCenter.Subscribe(Activity, Page.ActionSheetSignalName, OnActionSheetRequested); + WeakReferenceMessenger.Default.Register(this, static (r,m) => r.OnPageBusy(m)); + WeakReferenceMessenger.Default.Register(this, static (r, m) => r.OnAlertRequested(m)); + WeakReferenceMessenger.Default.Register(this, static (r, m) => r.OnPromptRequested(m)); + WeakReferenceMessenger.Default.Register(this, static (r, m) => r.OnActionSheetRequested(m)); } public Activity Activity { get; } @@ -75,10 +76,7 @@ internal AlertRequestHelper(Activity context, IMauiContext mauiContext) public void Dispose() { - MessagingCenter.Unsubscribe(Activity, Page.BusySetSignalName); - MessagingCenter.Unsubscribe(Activity, Page.AlertSignalName); - MessagingCenter.Unsubscribe(Activity, Page.PromptSignalName); - MessagingCenter.Unsubscribe(Activity, Page.ActionSheetSignalName); + WeakReferenceMessenger.Default.UnregisterAll(Activity); } public void ResetBusyCount() @@ -86,8 +84,11 @@ public void ResetBusyCount() _busyCount = 0; } - void OnPageBusy(IView sender, bool enabled) + void OnPageBusy(PageBusyMessage message) { + var sender = message.Page; + var enabled = message.IsBusy; + // Verify that the page making the request is part of this activity if (!PageIsInThisContext(sender)) { @@ -99,8 +100,11 @@ void OnPageBusy(IView sender, bool enabled) UpdateProgressBarVisibility(_busyCount > 0); } - void OnActionSheetRequested(IView sender, ActionSheetArguments arguments) + void OnActionSheetRequested(ActionSheetMessage message) { + var sender = message.Page; + var arguments = message.Arguments; + // Verify that the page making the request is part of this activity if (!PageIsInThisContext(sender)) { @@ -158,8 +162,11 @@ void OnActionSheetRequested(IView sender, ActionSheetArguments arguments) } } - void OnAlertRequested(IView sender, AlertArguments arguments) + void OnAlertRequested(PageAlertMessage message) { + var sender = message.Page; + var arguments = message.Arguments; + // Verify that the page making the request is part of this activity if (!PageIsInThisContext(sender)) { @@ -222,8 +229,11 @@ TextDirection GetTextDirection(IView sender, FlowDirection flowDirection) return TextDirection.Ltr; } - void OnPromptRequested(IView sender, PromptArguments arguments) + void OnPromptRequested(PromptMessage message) { + var sender = message.Page; + var arguments = message.Arguments; + // Verify that the page making the request is part of this activity if (!PageIsInThisContext(sender)) { @@ -303,7 +313,7 @@ bool PageIsInThisContext(IView page) { return false; } - + return nativeView.Context.GetActivity()?.Equals(Activity) ?? false; } diff --git a/src/Controls/src/Core/Platform/AlertManager/AlertManager.Windows.cs b/src/Controls/src/Core/Platform/AlertManager/AlertManager.Windows.cs index dfb01a40d136..08de02c9f3b0 100644 --- a/src/Controls/src/Core/Platform/AlertManager/AlertManager.Windows.cs +++ b/src/Controls/src/Core/Platform/AlertManager/AlertManager.Windows.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using CommunityToolkit.Mvvm.Messaging; using Microsoft.Maui.Controls.Internals; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; @@ -46,10 +47,10 @@ internal AlertRequestHelper(UI.Xaml.Window window, IMauiContext mauiContext) Window = window; MauiContext = mauiContext; - MessagingCenter.Subscribe(Window, Page.BusySetSignalName, OnPageBusy); - MessagingCenter.Subscribe(Window, Page.AlertSignalName, OnAlertRequested); - MessagingCenter.Subscribe(Window, Page.PromptSignalName, OnPromptRequested); - MessagingCenter.Subscribe(Window, Page.ActionSheetSignalName, OnActionSheetRequested); + WeakReferenceMessenger.Default.Register(this, static (r,m) => r.OnPageBusy(m)); + WeakReferenceMessenger.Default.Register(this, static (r, m) => r.OnAlertRequested(m)); + WeakReferenceMessenger.Default.Register(this, static (r, m) => r.OnPromptRequested(m)); + WeakReferenceMessenger.Default.Register(this, static (r, m) => r.OnActionSheetRequested(m)); } public UI.Xaml.Window Window { get; } @@ -57,19 +58,21 @@ internal AlertRequestHelper(UI.Xaml.Window window, IMauiContext mauiContext) public void Dispose() { - MessagingCenter.Unsubscribe(Window, Page.BusySetSignalName); - MessagingCenter.Unsubscribe(Window, Page.AlertSignalName); - MessagingCenter.Unsubscribe(Window, Page.PromptSignalName); - MessagingCenter.Unsubscribe(Window, Page.ActionSheetSignalName); + WeakReferenceMessenger.Default.UnregisterAll(this); } - void OnPageBusy(Page sender, bool enabled) + void OnPageBusy(PageBusyMessage message) { + var sender = message.Page; + var busy = message.IsBusy; + // TODO: Wrap the pages in a Canvas, and dynamically add a ProgressBar } - async void OnAlertRequested(Page sender, AlertArguments arguments) + async void OnAlertRequested(PageAlertMessage message) { + var arguments = message.Arguments; + string content = arguments.Message ?? string.Empty; string title = arguments.Title ?? string.Empty; @@ -113,8 +116,10 @@ async void OnAlertRequested(Page sender, AlertArguments arguments) CurrentAlert = null; } - async void OnPromptRequested(Page sender, PromptArguments arguments) + async void OnPromptRequested(PromptMessage message) { + var arguments = message.Arguments; + var promptDialog = new PromptDialog { Title = arguments.Title ?? string.Empty, @@ -147,8 +152,11 @@ async void OnPromptRequested(Page sender, PromptArguments arguments) CurrentPrompt = null; } - void OnActionSheetRequested(Page sender, ActionSheetArguments arguments) + void OnActionSheetRequested(ActionSheetMessage message) { + var sender = message.Page; + var arguments = message.Arguments; + bool userDidSelect = false; if (arguments.FlowDirection == FlowDirection.MatchParent) diff --git a/src/Controls/src/Core/Platform/AlertManager/AlertManager.iOS.cs b/src/Controls/src/Core/Platform/AlertManager/AlertManager.iOS.cs index eb259412057e..9c3fd5ab9e58 100644 --- a/src/Controls/src/Core/Platform/AlertManager/AlertManager.iOS.cs +++ b/src/Controls/src/Core/Platform/AlertManager/AlertManager.iOS.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using CommunityToolkit.Mvvm.Messaging; using Foundation; using Microsoft.Extensions.DependencyInjection; using Microsoft.Maui.Controls.Internals; @@ -49,41 +50,40 @@ internal AlertRequestHelper(UIWindow window) { Window = window; - MessagingCenter.Subscribe(Window, Page.BusySetSignalName, OnPageBusy); - MessagingCenter.Subscribe(Window, Page.AlertSignalName, OnAlertRequested); - MessagingCenter.Subscribe(Window, Page.PromptSignalName, OnPromptRequested); - MessagingCenter.Subscribe(Window, Page.ActionSheetSignalName, OnActionSheetRequested); + WeakReferenceMessenger.Default.Register(this, static (r,m) => r.OnPageBusy(m)); + WeakReferenceMessenger.Default.Register(this, static (r, m) => r.OnAlertRequested(m)); + WeakReferenceMessenger.Default.Register(this, static (r, m) => r.OnPromptRequested(m)); + WeakReferenceMessenger.Default.Register(this, static (r, m) => r.OnActionSheetRequested(m)); } public UIWindow Window { get; } public void Dispose() { - MessagingCenter.Unsubscribe(Window, Page.BusySetSignalName); - MessagingCenter.Unsubscribe(Window, Page.AlertSignalName); - MessagingCenter.Unsubscribe(Window, Page.PromptSignalName); - MessagingCenter.Unsubscribe(Window, Page.ActionSheetSignalName); + WeakReferenceMessenger.Default.UnregisterAll(this); } - void OnPageBusy(IView sender, bool enabled) + void OnPageBusy(PageBusyMessage message) { + var enabled = message.IsBusy; + _busyCount = Math.Max(0, enabled ? _busyCount + 1 : _busyCount - 1); UIApplication.SharedApplication.NetworkActivityIndicatorVisible = _busyCount > 0; } - void OnAlertRequested(IView sender, AlertArguments arguments) + void OnAlertRequested(PageAlertMessage message) { - PresentAlert(arguments); + PresentAlert(message.Arguments); } - void OnPromptRequested(IView sender, PromptArguments arguments) + void OnPromptRequested(PromptMessage message) { - PresentPrompt(arguments); + PresentPrompt(message.Arguments); } - void OnActionSheetRequested(IView sender, ActionSheetArguments arguments) + void OnActionSheetRequested(ActionSheetMessage message) { - PresentActionSheet(arguments); + PresentActionSheet(message.Arguments); } void PresentAlert(AlertArguments arguments) diff --git a/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs b/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs index a1dd194bc46c..760c25b8089b 100644 --- a/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs +++ b/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Android.cs @@ -11,6 +11,7 @@ using AndroidX.Fragment.App; using Microsoft.Maui.Graphics; using AView = Android.Views.View; +using CommunityToolkit.Mvvm.Messaging; namespace Microsoft.Maui.Controls.Platform { @@ -34,7 +35,7 @@ internal bool NavAnimationInProgress return; _navAnimationInProgress = value; if (value) - MessagingCenter.Send(this, CloseContextActionsSignalName); + WeakReferenceMessenger.Default.Send(new CloseContextActionsMessage()); } } diff --git a/src/Controls/src/Core/RadioButton.cs b/src/Controls/src/Core/RadioButton.cs index f7c85f648c5c..0bbc348f579d 100644 --- a/src/Controls/src/Core/RadioButton.cs +++ b/src/Controls/src/Core/RadioButton.cs @@ -1,4 +1,5 @@ using System; +using CommunityToolkit.Mvvm.Messaging; using Microsoft.Extensions.Logging; using Microsoft.Maui.Controls.Internals; using Microsoft.Maui.Controls.Shapes; @@ -15,9 +16,6 @@ public partial class RadioButton : TemplatedView, IElementConfiguration(this, - RadioButtonGroup.GroupSelectionChangedMessage, HandleRadioButtonGroupSelectionChanged); - MessagingCenter.Subscribe, RadioButtonGroupValueChanged>(this, - RadioButtonGroup.GroupValueChangedMessage, HandleRadioButtonGroupValueChanged); + WeakReferenceMessenger.Default.Register(this, static (r,m) => r.HandleRadioButtonGroupSelectionChanged(m)); + WeakReferenceMessenger.Default.Register(this, static (r,m) => r.HandleRadioButtonGroupValueChanged(m)); } - MessagingCenter.Send(this, GroupNameChangedMessage, - new RadioButtonGroupNameChanged(RadioButtonGroup.GetVisualRoot(this), oldGroupName)); + WeakReferenceMessenger.Default.Send(new RadioButtonGroupNameChanged(RadioButtonGroup.GetVisualRoot(this), oldGroupName)); } else { if (!string.IsNullOrEmpty(oldGroupName)) { - MessagingCenter.Unsubscribe(this, RadioButtonGroup.GroupSelectionChangedMessage); - MessagingCenter.Unsubscribe, RadioButtonGroupValueChanged>(this, RadioButtonGroup.GroupValueChangedMessage); + WeakReferenceMessenger.Default.Unregister(this); + WeakReferenceMessenger.Default.Unregister(this); } } } @@ -415,8 +409,10 @@ bool MatchesScope(RadioButtonScopeMessage message) return RadioButtonGroup.GetVisualRoot(this) == message.Scope; } - void HandleRadioButtonGroupSelectionChanged(RadioButton selected, RadioButtonGroupSelectionChanged args) + void HandleRadioButtonGroupSelectionChanged(RadioButtonGroupSelectionChanged args) { + var selected = args.RadioButton; + if (!IsChecked || selected == this || string.IsNullOrEmpty(GroupName) || GroupName != selected.GroupName || !MatchesScope(args)) { return; @@ -425,7 +421,7 @@ void HandleRadioButtonGroupSelectionChanged(RadioButton selected, RadioButtonGro IsChecked = false; } - void HandleRadioButtonGroupValueChanged(Compatibility.Layout layout, RadioButtonGroupValueChanged args) + void HandleRadioButtonGroupValueChanged(RadioButtonGroupValueChanged args) { if (IsChecked || string.IsNullOrEmpty(GroupName) || GroupName != args.GroupName || Value != args.Value || !MatchesScope(args)) { diff --git a/src/Controls/src/Core/RadioButtonGroup.cs b/src/Controls/src/Core/RadioButtonGroup.cs index a147540ba241..8dc1b754ea1b 100644 --- a/src/Controls/src/Core/RadioButtonGroup.cs +++ b/src/Controls/src/Core/RadioButtonGroup.cs @@ -1,12 +1,10 @@ using System.Collections; +using CommunityToolkit.Mvvm.Messaging; namespace Microsoft.Maui.Controls { public static class RadioButtonGroup { - internal const string GroupSelectionChangedMessage = "RadioButtonGroupSelectionChanged"; - internal const string GroupValueChangedMessage = "RadioButtonGroupValueChanged"; - static readonly BindableProperty RadioButtonGroupControllerProperty = BindableProperty.CreateAttached("RadioButtonGroupController", typeof(RadioButtonGroupController), typeof(Compatibility.Layout), default(RadioButtonGroupController), defaultValueCreator: (b) => new RadioButtonGroupController((Compatibility.Layout)b), @@ -54,8 +52,7 @@ internal static void UpdateRadioButtonGroup(RadioButton radioButton) ? GroupByParent(radioButton) : GetVisualRoot(radioButton); - MessagingCenter.Send(radioButton, GroupSelectionChangedMessage, - new RadioButtonGroupSelectionChanged(scope)); + WeakReferenceMessenger.Default.Send(new RadioButtonGroupSelectionChanged(scope, radioButton)); } internal static Element GroupByParent(RadioButton radioButton) diff --git a/src/Controls/src/Core/RadioButtonGroupController.cs b/src/Controls/src/Core/RadioButtonGroupController.cs index 85e35175ba09..ec83d14e0317 100644 --- a/src/Controls/src/Core/RadioButtonGroupController.cs +++ b/src/Controls/src/Core/RadioButtonGroupController.cs @@ -1,4 +1,5 @@ using System; +using CommunityToolkit.Mvvm.Messaging; namespace Microsoft.Maui.Controls { @@ -27,12 +28,9 @@ public RadioButtonGroupController(Compatibility.Layout layout) UpdateGroupNames(layout, _groupName); } - MessagingCenter.Subscribe(this, - RadioButtonGroup.GroupSelectionChangedMessage, HandleRadioButtonGroupSelectionChanged); - MessagingCenter.Subscribe(this, RadioButton.GroupNameChangedMessage, - HandleRadioButtonGroupNameChanged); - MessagingCenter.Subscribe(this, RadioButton.ValueChangedMessage, - HandleRadioButtonValueChanged); + WeakReferenceMessenger.Default.Register(this, static (r,m) => r.HandleRadioButtonGroupSelectionChanged(m)); + WeakReferenceMessenger.Default.Register(this, static (r,m) => r.HandleRadioButtonGroupNameChanged(m)); + WeakReferenceMessenger.Default.Register(this, static (r,m) => r.HandleRadioButtonValueChanged(m)); } bool MatchesScope(RadioButtonScopeMessage message) @@ -40,8 +38,10 @@ bool MatchesScope(RadioButtonScopeMessage message) return RadioButtonGroup.GetVisualRoot(_layout) == message.Scope; } - void HandleRadioButtonGroupSelectionChanged(RadioButton selected, RadioButtonGroupSelectionChanged args) + void HandleRadioButtonGroupSelectionChanged(RadioButtonGroupSelectionChanged args) { + var selected = args.RadioButton; + if (selected.GroupName != _groupName || !MatchesScope(args)) { return; @@ -50,7 +50,7 @@ void HandleRadioButtonGroupSelectionChanged(RadioButton selected, RadioButtonGro _layout.SetValue(RadioButtonGroup.SelectedValueProperty, selected.Value); } - void HandleRadioButtonGroupNameChanged(RadioButton radioButton, RadioButtonGroupNameChanged args) + void HandleRadioButtonGroupNameChanged(RadioButtonGroupNameChanged args) { if (args.OldName != _groupName || !MatchesScope(args)) { @@ -60,8 +60,10 @@ void HandleRadioButtonGroupNameChanged(RadioButton radioButton, RadioButtonGroup _layout.ClearValue(RadioButtonGroup.SelectedValueProperty); } - void HandleRadioButtonValueChanged(RadioButton radioButton, RadioButtonValueChanged args) + void HandleRadioButtonValueChanged(RadioButtonValueChanged args) { + var radioButton = args.RadioButton; + if (radioButton.GroupName != _groupName || !MatchesScope(args)) { return; @@ -132,8 +134,7 @@ void SetSelectedValue(object radioButtonValue) if (radioButtonValue != null) { - MessagingCenter.Send(_layout, RadioButtonGroup.GroupValueChangedMessage, - new RadioButtonGroupValueChanged(_groupName, RadioButtonGroup.GetVisualRoot(_layout), radioButtonValue)); + WeakReferenceMessenger.Default.Send(new RadioButtonGroupValueChanged(RadioButtonGroup.GetVisualRoot(_layout), radioButtonValue, _groupName)); } } diff --git a/src/Controls/src/Core/RadioButtonGroupSelectionChanged.cs b/src/Controls/src/Core/RadioButtonGroupSelectionChanged.cs deleted file mode 100644 index 78e731c4b92d..000000000000 --- a/src/Controls/src/Core/RadioButtonGroupSelectionChanged.cs +++ /dev/null @@ -1,41 +0,0 @@ -namespace Microsoft.Maui.Controls -{ - internal abstract class RadioButtonScopeMessage - { - public Element Scope { get; } - - protected RadioButtonScopeMessage(Element scope) => Scope = scope; - } - - internal class RadioButtonGroupSelectionChanged : RadioButtonScopeMessage - { - public RadioButtonGroupSelectionChanged(Element scope) : base(scope) { } - } - - internal class RadioButtonGroupNameChanged : RadioButtonScopeMessage - { - public string OldName { get; } - - public RadioButtonGroupNameChanged(Element scope, string oldName) : base(scope) - { - OldName = oldName; - } - } - - internal class RadioButtonValueChanged : RadioButtonScopeMessage - { - public RadioButtonValueChanged(Element scope) : base(scope) { } - } - - internal class RadioButtonGroupValueChanged : RadioButtonScopeMessage - { - public object Value { get; } - public string GroupName { get; } - - public RadioButtonGroupValueChanged(string groupName, Element scope, object value) : base(scope) - { - GroupName = groupName; - Value = value; - } - } -} \ No newline at end of file diff --git a/src/Controls/src/Core/RadioButtonMessages.cs b/src/Controls/src/Core/RadioButtonMessages.cs new file mode 100644 index 000000000000..ad51d711da19 --- /dev/null +++ b/src/Controls/src/Core/RadioButtonMessages.cs @@ -0,0 +1,16 @@ +namespace Microsoft.Maui.Controls +{ + internal abstract record RadioButtonScopeMessage(Element Scope); + + internal sealed record RadioButtonGroupSelectionChanged(Element Scope, RadioButton RadioButton) + : RadioButtonScopeMessage(Scope); + + internal sealed record RadioButtonGroupNameChanged(Element Scope, string OldName) + : RadioButtonScopeMessage(Scope); + + internal sealed record RadioButtonValueChanged(Element Scope, RadioButton RadioButton) + : RadioButtonScopeMessage(Scope); + + internal sealed record RadioButtonGroupValueChanged (Element Scope, object Value, string GroupName) + : RadioButtonScopeMessage(Scope); +} \ No newline at end of file diff --git a/src/Controls/tests/Core.UnitTests/MapTests.cs b/src/Controls/tests/Core.UnitTests/MapTests.cs index 4eca8131cdb4..8aa7b1113c72 100644 --- a/src/Controls/tests/Core.UnitTests/MapTests.cs +++ b/src/Controls/tests/Core.UnitTests/MapTests.cs @@ -4,6 +4,7 @@ using System.Linq; using Microsoft.Maui.Controls.Maps; using NUnit.Framework; +using CommunityToolkit.Mvvm.Messaging; namespace Microsoft.Maui.Controls.Core.UnitTests { @@ -127,11 +128,12 @@ public void VisibleRegion() Assert.AreEqual(null, map.VisibleRegion); bool signaled = false; - MessagingCenter.Subscribe(this, "MapMoveToRegion", (s, a) => + + WeakReferenceMessenger.Default.Register(this, (receiver, args) => { signaled = true; - map.SetVisibleRegion(a); - }, map); + map.SetVisibleRegion(args); + }); map.MoveToRegion(new MapSpan(new Position(1, 2), 3, 4)); Assert.AreEqual(new MapSpan(new Position(1, 2), 3, 4), map.LastMoveToRegion); diff --git a/src/Controls/tests/Core.UnitTests/PageTests.cs b/src/Controls/tests/Core.UnitTests/PageTests.cs index 384efe4f61ba..4bb350ea2d45 100644 --- a/src/Controls/tests/Core.UnitTests/PageTests.cs +++ b/src/Controls/tests/Core.UnitTests/PageTests.cs @@ -4,6 +4,7 @@ using Microsoft.Maui.Controls.Internals; using Microsoft.Maui.Graphics; using NUnit.Framework; +using CommunityToolkit.Mvvm.Messaging; namespace Microsoft.Maui.Controls.Core.UnitTests { @@ -14,7 +15,7 @@ public class PageTests : BaseTestFixture public override void TearDown() { base.TearDown(); - MessagingCenter.ClearSubscribers(); + WeakReferenceMessenger.Default.Reset(); } [Test] @@ -308,7 +309,8 @@ public void TestThrowOnInvalidAlignment() public void BusyNotSentWhenNotVisible() { var sent = false; - MessagingCenter.Subscribe(this, Page.BusySetSignalName, (p, b) => sent = true); + + WeakReferenceMessenger.Default.Register(this, (r, m) => sent = true); new ContentPage { IsBusy = true }; @@ -319,9 +321,10 @@ public void BusyNotSentWhenNotVisible() public void BusySentWhenBusyPageAppears() { var sent = false; - MessagingCenter.Subscribe(this, Page.BusySetSignalName, (p, b) => + + WeakReferenceMessenger.Default.Register(this, (r, m) => { - Assert.That(b, Is.True); + Assert.That(m.IsBusy, Is.True); sent = true; }); @@ -342,9 +345,9 @@ public void BusySentWhenBusyPageDisappears() ((IPageController)page).SendAppearing(); var sent = false; - MessagingCenter.Subscribe(this, Page.BusySetSignalName, (p, b) => + WeakReferenceMessenger.Default.Register(this, (r, m) => { - Assert.That(b, Is.False); + Assert.That(m.IsBusy, Is.True); sent = true; }); @@ -357,7 +360,7 @@ public void BusySentWhenBusyPageDisappears() public void BusySentWhenVisiblePageSetToBusy() { var sent = false; - MessagingCenter.Subscribe(this, Page.BusySetSignalName, (p, b) => sent = true); + WeakReferenceMessenger.Default.Register(this, (r, m) => sent = true); var page = new ContentPage(); _ = new Window(page); @@ -376,7 +379,7 @@ public void DisplayAlert() var page = new ContentPage() { IsPlatformEnabled = true }; AlertArguments args = null; - MessagingCenter.Subscribe(this, Page.AlertSignalName, (Page sender, AlertArguments e) => args = e); + WeakReferenceMessenger.Default.Register(this, (r, m) => args = m.Arguments); var task = page.DisplayAlert("Title", "Message", "Accept", "Cancel"); @@ -399,7 +402,8 @@ public void DisplayActionSheet() var page = new ContentPage() { IsPlatformEnabled = true }; ActionSheetArguments args = null; - MessagingCenter.Subscribe(this, Page.ActionSheetSignalName, (Page sender, ActionSheetArguments e) => args = e); + + WeakReferenceMessenger.Default.Register(this, (r, m) => args = m.Arguments); var task = page.DisplayActionSheet("Title", "Cancel", "Destruction", "Other 1", "Other 2");