diff --git a/src/Uno.Toolkit.UI/Controls/NavigationBar/NativeNavigationBarPresenter.Android.cs b/src/Uno.Toolkit.UI/Controls/NavigationBar/NativeNavigationBarPresenter.Android.cs index fda1fdda3..ee10c13e6 100644 --- a/src/Uno.Toolkit.UI/Controls/NavigationBar/NativeNavigationBarPresenter.Android.cs +++ b/src/Uno.Toolkit.UI/Controls/NavigationBar/NativeNavigationBarPresenter.Android.cs @@ -26,13 +26,12 @@ namespace Uno.Toolkit.UI { - public partial class NativeNavigationBarPresenter : ContentPresenter, INavigationBarPresenter + public partial class NativeNavigationBarPresenter { private SerialDisposable _mainCommandClickHandler = new SerialDisposable(); public NativeNavigationBarPresenter() { - Loaded += OnLoaded; Unloaded += OnUnloaded; } @@ -41,29 +40,24 @@ private void OnUnloaded(object sender, RoutedEventArgs e) _mainCommandClickHandler.Disposable = null; } - public void SetOwner(NavigationBar navigationBar) + private void OnMainCommandClicked(object sender, RoutedEventArgs e) { - //Owner is accessed through TemplatedParent on Uno platforms + var navBar = GetNavBar(); + navBar?.TryPerformMainCommand(); } - private void OnLoaded(object sender, RoutedEventArgs e) + partial void OnOwnerChanged() { - var navBar = TemplatedParent as NavigationBar; - if (navBar is { }) + _mainCommandClickHandler.Disposable = null; + + if (GetNavBar() is { } navBar) { Content = navBar.GetOrAddDefaultRenderer().Native; ContentTemplate = null; // normally, the ContentTemplate is inherited from the NavigationBar, but in this case, we don't want it to. We want to use the renderer directly as the child. navBar.MainCommand.Click += OnMainCommandClicked; - _mainCommandClickHandler.Disposable = null; _mainCommandClickHandler.Disposable = Disposable.Create(() => navBar.MainCommand.Click -= OnMainCommandClicked); } } - - private void OnMainCommandClicked(object sender, RoutedEventArgs e) - { - var navBar = TemplatedParent as NavigationBar; - navBar?.TryPerformMainCommand(); - } } } #endif diff --git a/src/Uno.Toolkit.UI/Controls/NavigationBar/NativeNavigationBarPresenter.cs b/src/Uno.Toolkit.UI/Controls/NavigationBar/NativeNavigationBarPresenter.cs new file mode 100644 index 000000000..aeeb64825 --- /dev/null +++ b/src/Uno.Toolkit.UI/Controls/NavigationBar/NativeNavigationBarPresenter.cs @@ -0,0 +1,60 @@ +#if __ANDROID__ || __IOS__ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Uno.Disposables; + +#if IS_WINUI +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Controls.Primitives; +using Microsoft.UI.Xaml.Data; +using Microsoft.UI.Xaml.Input; +using Microsoft.UI.Xaml.Media; +using Microsoft.UI.Xaml.Navigation; +#else +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Navigation; +#endif + +namespace Uno.Toolkit.UI +{ + partial class NativeNavigationBarPresenter : ContentPresenter, INavigationBarPresenter + { + private WeakReference? _weakNavBar; + + public void SetOwner(NavigationBar? navigationBar) + { + if (GetNavBar() == navigationBar) + { + return; + } + _weakNavBar = new WeakReference(navigationBar); + + OnOwnerChanged(); + } + + private NavigationBar? GetNavBar() + { + if (_weakNavBar == null) + { + return null; + } + + NavigationBar? targetNavBar = null; + if (_weakNavBar.TryGetTarget(out targetNavBar)) + { + return targetNavBar; + } + + return null; + } + + partial void OnOwnerChanged(); + } +} +#endif diff --git a/src/Uno.Toolkit.UI/Controls/NavigationBar/NativeNavigationBarPresenter.iOS.cs b/src/Uno.Toolkit.UI/Controls/NavigationBar/NativeNavigationBarPresenter.iOS.cs index c737f2f18..f1943188c 100644 --- a/src/Uno.Toolkit.UI/Controls/NavigationBar/NativeNavigationBarPresenter.iOS.cs +++ b/src/Uno.Toolkit.UI/Controls/NavigationBar/NativeNavigationBarPresenter.iOS.cs @@ -31,26 +31,19 @@ namespace Uno.Toolkit.UI { - public partial class NativeNavigationBarPresenter : ContentPresenter, INavigationBarPresenter + public partial class NativeNavigationBarPresenter { private readonly SerialDisposable _statusBarSubscription = new SerialDisposable(); private readonly SerialDisposable _orientationSubscription = new SerialDisposable(); private SerialDisposable _mainCommandClickHandler = new SerialDisposable(); - private WeakReference? _navBarRef; private readonly bool _isPhone = UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Phone; public NativeNavigationBarPresenter() { - Loaded += OnLoaded; Unloaded += OnUnloaded; } - public void SetOwner(NavigationBar navigationBar) - { - //Owner is accessed through TemplatedParent on Uno platforms - } - private void OnUnloaded(object sender, RoutedEventArgs e) { _statusBarSubscription.Disposable = null; @@ -58,24 +51,16 @@ private void OnUnloaded(object sender, RoutedEventArgs e) _mainCommandClickHandler.Disposable = null; } - private void OnLoaded(object sender, RoutedEventArgs e) + partial void OnOwnerChanged() { // TODO: Find a proper way to decide whether a NavigationBar exists on canvas (within Page), or is mapped to the UINavigationController's NavigationBar. - NavigationBar? navBar = null; - - _navBarRef?.TryGetTarget(out navBar); - - if (navBar == null) - { - navBar = TemplatedParent as NavigationBar; - _navBarRef = new WeakReference(navBar); - } + _mainCommandClickHandler.Disposable = null; - if (navBar is { }) + if (GetNavBar() is { } navBar) { navBar.MainCommand.Click += OnMainCommandClick; - _mainCommandClickHandler.Disposable = null; + _mainCommandClickHandler.Disposable = Disposable.Create(() => navBar.MainCommand.Click -= OnMainCommandClick); LayoutNativeNavBar(navBar); @@ -122,11 +107,8 @@ void OnStatusBarChanged(XamlStatusBar sender, object args) private void OnMainCommandClick(object sender, RoutedEventArgs e) { - NavigationBar? navBar = null; - if (_navBarRef?.TryGetTarget(out navBar) ?? false) - { - navBar?.TryPerformMainCommand(); - } + var navBar = GetNavBar(); + navBar?.TryPerformMainCommand(); } protected override Size MeasureOverride(Size size)