From 5afe02cbc782ab1c31ae1e581c2de6fc1b4338a8 Mon Sep 17 00:00:00 2001 From: Prathamesh Narkhede Date: Wed, 28 Aug 2024 12:21:18 -0700 Subject: [PATCH 01/10] Document known MAUI iOS issue in ItemTemplateChanged --- src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs b/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs index f91f3a887..77355177a 100644 --- a/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs +++ b/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs @@ -156,6 +156,9 @@ private static void GeoViewChanged(BindableObject sender, object? oldValue, obje /// private static void ItemTemplateChanged(BindableObject sender, object? oldValue, object? newValue) { + // MAUI Bug: Custom Control ItemTemplate fails to change at runtime in MAUI iOS + // GitHub Issue: #24492 (https://github.com/dotnet/maui/issues/24492) + BookmarksView bookmarkView = (BookmarksView)sender; if (bookmarkView._presentingView != null) From 475793dfac69b735be4155b05ca609ca43756e85 Mon Sep 17 00:00:00 2001 From: Prathamesh Narkhede Date: Thu, 29 Aug 2024 18:37:42 -0700 Subject: [PATCH 02/10] Refactor UI: Replace ListView with CollectionView --- .../Samples/BookmarksViewSample.xaml | 6 +-- .../BookmarksView/BookmarksView.cs | 45 +++++++++---------- 2 files changed, 22 insertions(+), 29 deletions(-) diff --git a/src/Samples/Toolkit.SampleApp.Maui/Samples/BookmarksViewSample.xaml b/src/Samples/Toolkit.SampleApp.Maui/Samples/BookmarksViewSample.xaml index 0ac38ae35..8cdfb7823 100644 --- a/src/Samples/Toolkit.SampleApp.Maui/Samples/BookmarksViewSample.xaml +++ b/src/Samples/Toolkit.SampleApp.Maui/Samples/BookmarksViewSample.xaml @@ -10,12 +10,10 @@ x:Class="Toolkit.SampleApp.Maui.Samples.BookmarksViewSample"> - + - - + diff --git a/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs b/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs index 77355177a..744e8d3cd 100644 --- a/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs +++ b/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs @@ -24,7 +24,7 @@ namespace Esri.ArcGISRuntime.Toolkit.Maui; /// public class BookmarksView : TemplatedView { - private ListView? _presentingView; + private CollectionView? _presentingView; private BookmarksViewDataSource _dataSource = new BookmarksViewDataSource(); private static readonly DataTemplate DefaultDataTemplate; @@ -35,18 +35,17 @@ static BookmarksView() { DefaultDataTemplate = new DataTemplate(() => { - var defaultCell = new TextCell(); - defaultCell.SetBinding(TextCell.TextProperty, nameof(Bookmark.Name)); - return defaultCell; + var defaultLabel = new Label(); + defaultLabel.SetBinding(Label.TextProperty, nameof(Bookmark.Name)); + return defaultLabel; }); - string template = @" - - - RecycleElement - - - "; + string template = + @" + + "; DefaultControlTemplate = Microsoft.Maui.Controls.Xaml.Extensions.LoadFromXaml(new ControlTemplate(), template); } @@ -69,14 +68,14 @@ protected override void OnApplyTemplate() if (_presentingView != null) { - _presentingView.ItemSelected -= Internal_bookmarkSelected; + _presentingView.SelectionChanged -= Internal_bookmarkSelected; } - _presentingView = GetTemplateChild("PresentingView") as ListView; + _presentingView = GetTemplateChild("PresentingView") as CollectionView; if (_presentingView != null) { - _presentingView.ItemSelected += Internal_bookmarkSelected; + _presentingView.SelectionChanged += Internal_bookmarkSelected; _presentingView.ItemTemplate = ItemTemplate; _presentingView.ItemsSource = _dataSource; } @@ -156,9 +155,6 @@ private static void GeoViewChanged(BindableObject sender, object? oldValue, obje /// private static void ItemTemplateChanged(BindableObject sender, object? oldValue, object? newValue) { - // MAUI Bug: Custom Control ItemTemplate fails to change at runtime in MAUI iOS - // GitHub Issue: #24492 (https://github.com/dotnet/maui/issues/24492) - BookmarksView bookmarkView = (BookmarksView)sender; if (bookmarkView._presentingView != null) @@ -195,16 +191,15 @@ private void SelectAndNavigateToBookmark(Bookmark bookmark) /// /// Handles selection on the underlying list view. /// - private void Internal_bookmarkSelected(object? sender, SelectedItemChangedEventArgs e) + private void Internal_bookmarkSelected(object? sender, SelectionChangedEventArgs e) { - if (e.SelectedItem is Bookmark bm) - { - SelectAndNavigateToBookmark(bm); - } - - if (e.SelectedItem != null && sender is ListView lv) + if (sender is CollectionView cv) { - lv.SelectedItem = null; + if (cv.SelectedItem is Bookmark item) + { + SelectAndNavigateToBookmark(item); + } + cv.ClearValue(CollectionView.SelectedItemProperty); } } From 4d65c759080a5c715f68f877308cef9ffafdaad7 Mon Sep 17 00:00:00 2001 From: Prathamesh Narkhede Date: Tue, 3 Sep 2024 11:52:59 -0700 Subject: [PATCH 03/10] Refactor BookmarksView to centralize CollectionView updates - This Fixes a bug with Android adding item couple of times when new Bookmark is added. - Centralize the update logic for the CollectionView in the BookmarksView class by introducing a new `UpdateListView` method. --- .../BookmarksView/BookmarksView.cs | 57 +++++++++---------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs b/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs index 744e8d3cd..b6083d4c7 100644 --- a/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs +++ b/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs @@ -14,6 +14,7 @@ // * limitations under the License. // ******************************************************************************/ using Esri.ArcGISRuntime.Mapping; +using System.Collections.Specialized; using System.Diagnostics.CodeAnalysis; namespace Esri.ArcGISRuntime.Toolkit.Maui; @@ -24,7 +25,6 @@ namespace Esri.ArcGISRuntime.Toolkit.Maui; /// public class BookmarksView : TemplatedView { - private CollectionView? _presentingView; private BookmarksViewDataSource _dataSource = new BookmarksViewDataSource(); private static readonly DataTemplate DefaultDataTemplate; @@ -55,8 +55,11 @@ static BookmarksView() public BookmarksView() { ItemTemplate = DefaultDataTemplate; - ControlTemplate = DefaultControlTemplate; +#if ANDROID + // This Fixes a bug with Android adding item couple of times when new Bookmark is added to BookmarkCollection. + _dataSource.CollectionChanged += OnBookmarksCollectionChanged; +#endif } /// @@ -65,20 +68,7 @@ public BookmarksView() protected override void OnApplyTemplate() { base.OnApplyTemplate(); - - if (_presentingView != null) - { - _presentingView.SelectionChanged -= Internal_bookmarkSelected; - } - - _presentingView = GetTemplateChild("PresentingView") as CollectionView; - - if (_presentingView != null) - { - _presentingView.SelectionChanged += Internal_bookmarkSelected; - _presentingView.ItemTemplate = ItemTemplate; - _presentingView.ItemsSource = _dataSource; - } + UpdateListView(); } /// @@ -156,19 +146,7 @@ private static void GeoViewChanged(BindableObject sender, object? oldValue, obje private static void ItemTemplateChanged(BindableObject sender, object? oldValue, object? newValue) { BookmarksView bookmarkView = (BookmarksView)sender; - - if (bookmarkView._presentingView != null) - { - bookmarkView._presentingView.ItemTemplate = newValue as DataTemplate; - -#if WINDOWS - // This workaround addresses an issue with MAUI WinUI. - // Without refreshing the items source of the BookmarksView ListView the change is not reflected in the UI. - var existingItems = bookmarkView._presentingView.ItemsSource; - bookmarkView._presentingView.ItemsSource = null; - bookmarkView._presentingView.ItemsSource = existingItems; -#endif - } + bookmarkView.UpdateListView(); } /// @@ -203,6 +181,27 @@ private void Internal_bookmarkSelected(object? sender, SelectionChangedEventArgs } } + private void UpdateListView() + { + var collection = (CollectionView)GetTemplateChild("PresentingView"); + if (collection != null) + { + collection.SelectionChanged -= Internal_bookmarkSelected; + collection.SelectionChanged += Internal_bookmarkSelected; + collection.ItemTemplate = null; + collection.ItemTemplate = ItemTemplate; + collection.ItemsSource = _dataSource; + } + } + + private void OnBookmarksCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) + { + if (e.Action is NotifyCollectionChangedAction.Add) + { + UpdateListView(); + } + } + /// /// Raised whenever a bookmark is selected. /// From 4d8c05c7de51e2c4cd194d49784615fdbc61c17b Mon Sep 17 00:00:00 2001 From: Prathamesh Narkhede Date: Tue, 3 Sep 2024 11:55:26 -0700 Subject: [PATCH 04/10] Refactor: centralize "PresentingView" string usage --- src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs b/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs index b6083d4c7..ca1c04fc8 100644 --- a/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs +++ b/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs @@ -26,6 +26,7 @@ namespace Esri.ArcGISRuntime.Toolkit.Maui; public class BookmarksView : TemplatedView { private BookmarksViewDataSource _dataSource = new BookmarksViewDataSource(); + private const string _presentingViewName = "PresentingView"; private static readonly DataTemplate DefaultDataTemplate; private static readonly ControlTemplate DefaultControlTemplate; @@ -41,10 +42,10 @@ static BookmarksView() }); string template = - @" - + "; DefaultControlTemplate = Microsoft.Maui.Controls.Xaml.Extensions.LoadFromXaml(new ControlTemplate(), template); } @@ -183,7 +184,7 @@ private void Internal_bookmarkSelected(object? sender, SelectionChangedEventArgs private void UpdateListView() { - var collection = (CollectionView)GetTemplateChild("PresentingView"); + var collection = (CollectionView)GetTemplateChild(_presentingViewName); if (collection != null) { collection.SelectionChanged -= Internal_bookmarkSelected; From 9660568f47111a15affa35562b32a8dbf4f0e5bf Mon Sep 17 00:00:00 2001 From: Prathamesh Narkhede Date: Tue, 3 Sep 2024 16:34:13 -0700 Subject: [PATCH 05/10] Changing name --- src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs b/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs index ca1c04fc8..d7c3b2bc7 100644 --- a/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs +++ b/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs @@ -69,7 +69,7 @@ public BookmarksView() protected override void OnApplyTemplate() { base.OnApplyTemplate(); - UpdateListView(); + UpdatePresentingView(); } /// @@ -147,7 +147,7 @@ private static void GeoViewChanged(BindableObject sender, object? oldValue, obje private static void ItemTemplateChanged(BindableObject sender, object? oldValue, object? newValue) { BookmarksView bookmarkView = (BookmarksView)sender; - bookmarkView.UpdateListView(); + bookmarkView.UpdatePresentingView(); } /// @@ -182,7 +182,7 @@ private void Internal_bookmarkSelected(object? sender, SelectionChangedEventArgs } } - private void UpdateListView() + private void UpdatePresentingView() { var collection = (CollectionView)GetTemplateChild(_presentingViewName); if (collection != null) @@ -199,7 +199,7 @@ private void OnBookmarksCollectionChanged(object? sender, NotifyCollectionChange { if (e.Action is NotifyCollectionChangedAction.Add) { - UpdateListView(); + UpdatePresentingView(); } } From c6d0cccc680969948758a2ff2b82125107dbc1f7 Mon Sep 17 00:00:00 2001 From: Prathamesh Narkhede Date: Tue, 3 Sep 2024 17:31:35 -0700 Subject: [PATCH 06/10] Refactor event handling in BookmarksView and DataSource This fixes problem in Android from root level. --- .../BookmarksView/BookmarksView.cs | 35 ++++++-------- .../BookmarksView/BookmarksViewDataSource.cs | 46 ++++++++++++------- 2 files changed, 43 insertions(+), 38 deletions(-) diff --git a/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs b/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs index d7c3b2bc7..59342b348 100644 --- a/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs +++ b/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs @@ -14,7 +14,6 @@ // * limitations under the License. // ******************************************************************************/ using Esri.ArcGISRuntime.Mapping; -using System.Collections.Specialized; using System.Diagnostics.CodeAnalysis; namespace Esri.ArcGISRuntime.Toolkit.Maui; @@ -57,10 +56,6 @@ public BookmarksView() { ItemTemplate = DefaultDataTemplate; ControlTemplate = DefaultControlTemplate; -#if ANDROID - // This Fixes a bug with Android adding item couple of times when new Bookmark is added to BookmarkCollection. - _dataSource.CollectionChanged += OnBookmarksCollectionChanged; -#endif } /// @@ -69,6 +64,13 @@ public BookmarksView() protected override void OnApplyTemplate() { base.OnApplyTemplate(); + + var collectionView = (CollectionView)GetTemplateChild(_presentingViewName); + if (collectionView is CollectionView view) + { + view.SelectionChanged -= Internal_bookmarkSelected; + view.SelectionChanged += Internal_bookmarkSelected; + } UpdatePresentingView(); } @@ -146,8 +148,8 @@ private static void GeoViewChanged(BindableObject sender, object? oldValue, obje /// private static void ItemTemplateChanged(BindableObject sender, object? oldValue, object? newValue) { - BookmarksView bookmarkView = (BookmarksView)sender; - bookmarkView.UpdatePresentingView(); + BookmarksView bookmarksView = (BookmarksView)sender; + bookmarksView.UpdatePresentingView(); } /// @@ -184,22 +186,11 @@ private void Internal_bookmarkSelected(object? sender, SelectionChangedEventArgs private void UpdatePresentingView() { - var collection = (CollectionView)GetTemplateChild(_presentingViewName); - if (collection != null) - { - collection.SelectionChanged -= Internal_bookmarkSelected; - collection.SelectionChanged += Internal_bookmarkSelected; - collection.ItemTemplate = null; - collection.ItemTemplate = ItemTemplate; - collection.ItemsSource = _dataSource; - } - } - - private void OnBookmarksCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) - { - if (e.Action is NotifyCollectionChangedAction.Add) + var collectionView = (CollectionView)GetTemplateChild(_presentingViewName); + if (collectionView is CollectionView view) { - UpdatePresentingView(); + view.ItemTemplate = ItemTemplate; + view.ItemsSource = _dataSource; } } diff --git a/src/Toolkit/Toolkit/UI/Controls/BookmarksView/BookmarksViewDataSource.cs b/src/Toolkit/Toolkit/UI/Controls/BookmarksView/BookmarksViewDataSource.cs index a811939c2..fb259e718 100644 --- a/src/Toolkit/Toolkit/UI/Controls/BookmarksView/BookmarksViewDataSource.cs +++ b/src/Toolkit/Toolkit/UI/Controls/BookmarksView/BookmarksViewDataSource.cs @@ -38,6 +38,9 @@ namespace Esri.ArcGISRuntime.Toolkit.UI.Controls internal class BookmarksViewDataSource : IList, INotifyCollectionChanged, INotifyPropertyChanged, IList { private GeoView? _geoView; + private WeakEventListener? _geoViewBookmarksListener; + private WeakEventListener? _geoViewLoadListener; + private new WeakEventListener? _overrideListListener; private IList? _overrideList; private IList ActiveBookmarkList @@ -93,10 +96,13 @@ public void SetOverrideList(IEnumerable? bookmarks) // Subscribe to events if applicable if (bookmarks is INotifyCollectionChanged iCollectionChanged) { - var listener = new WeakEventListener(this, iCollectionChanged); - listener.OnEventAction = static (instance, source, eventArgs) => instance.HandleOverrideListCollectionChanged(source, eventArgs); - listener.OnDetachAction = static (instance, source, weakEventListener) => source.CollectionChanged -= weakEventListener.OnEvent; - iCollectionChanged.CollectionChanged += listener.OnEvent; + _overrideListListener?.Detach(); + _overrideListListener = new WeakEventListener(this, iCollectionChanged) + { + OnEventAction = static (instance, source, eventArgs) => instance.HandleOverrideListCollectionChanged(source, eventArgs), + OnDetachAction = static (instance, source, weakEventListener) => source.CollectionChanged -= weakEventListener.OnEvent + }; + iCollectionChanged.CollectionChanged += _overrideListListener.OnEvent; } } @@ -188,13 +194,16 @@ private void GeoView_PropertyChanged(object? sender, PropertyChangedEventArgs e) private void GeoViewDocumentChanged(object? sender, object? e) { + _geoViewLoadListener?.Detach(); if (_geoView is MapView mv && mv.Map is ILoadable mapLoadable) { // Listen for load completion - var listener = new WeakEventListener(this, mapLoadable); - listener.OnEventAction = static (instance, source, eventArgs) => instance.Doc_Loaded(source, eventArgs); - listener.OnDetachAction = static (instance, source, weakEventListener) => source.Loaded -= weakEventListener.OnEvent; - mapLoadable.Loaded += listener.OnEvent; + _geoViewLoadListener = new WeakEventListener(this, mapLoadable) + { + OnEventAction = static (instance, source, eventArgs) => instance.Doc_Loaded(source, eventArgs), + OnDetachAction = static (instance, source, weakEventListener) => source.Loaded -= weakEventListener.OnEvent + }; + mapLoadable.Loaded += _geoViewLoadListener.OnEvent; // Ensure event is raised even if already loaded _ = mv.Map.RetryLoadAsync(); @@ -202,10 +211,12 @@ private void GeoViewDocumentChanged(object? sender, object? e) else if (_geoView is SceneView sv && sv.Scene is ILoadable sceneLoadable) { // Listen for load completion - var listener = new WeakEventListener(this, sceneLoadable); - listener.OnEventAction = static (instance, source, eventArgs) => instance.Doc_Loaded(source, eventArgs); - listener.OnDetachAction = static (instance, source, weakEventListener) => source.Loaded -= weakEventListener.OnEvent; - sceneLoadable.Loaded += listener.OnEvent; + _geoViewLoadListener = new WeakEventListener(this, sceneLoadable) + { + OnEventAction = static (instance, source, eventArgs) => instance.Doc_Loaded(source, eventArgs), + OnDetachAction = static (instance, source, weakEventListener) => source.Loaded -= weakEventListener.OnEvent + }; + sceneLoadable.Loaded += _geoViewLoadListener.OnEvent; // Ensure event is raised even if already loaded _ = sv.Scene.RetryLoadAsync(); @@ -240,10 +251,13 @@ private void Doc_Loaded(object? sender, EventArgs e) OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); } - var listener = new WeakEventListener(this, bmCollection); - listener.OnEventAction = static (instance, source, eventArgs) => instance.HandleGeoViewBookmarksCollectionChanged(source, eventArgs); - listener.OnDetachAction = static (instance, source, weakEventListener) => source.CollectionChanged -= weakEventListener.OnEvent; - bmCollection.CollectionChanged += listener.OnEvent; + _geoViewBookmarksListener?.Detach(); + _geoViewBookmarksListener = new WeakEventListener(this, bmCollection) + { + OnEventAction = static (instance, source, eventArgs) => instance.HandleGeoViewBookmarksCollectionChanged(source, eventArgs), + OnDetachAction = static (instance, source, weakEventListener) => source.CollectionChanged -= weakEventListener.OnEvent + }; + bmCollection.CollectionChanged += _geoViewBookmarksListener.OnEvent; } private void HandleGeoViewBookmarksCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) From e71bfd7bacb56c1d91a27b3060ee6160be807532 Mon Sep 17 00:00:00 2001 From: Prathamesh Narkhede Date: Tue, 3 Sep 2024 17:34:25 -0700 Subject: [PATCH 07/10] Removing unnecessary keyword --- .../UI/Controls/BookmarksView/BookmarksViewDataSource.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Toolkit/Toolkit/UI/Controls/BookmarksView/BookmarksViewDataSource.cs b/src/Toolkit/Toolkit/UI/Controls/BookmarksView/BookmarksViewDataSource.cs index fb259e718..5b91866c7 100644 --- a/src/Toolkit/Toolkit/UI/Controls/BookmarksView/BookmarksViewDataSource.cs +++ b/src/Toolkit/Toolkit/UI/Controls/BookmarksView/BookmarksViewDataSource.cs @@ -40,7 +40,7 @@ internal class BookmarksViewDataSource : IList, INotifyCollectionChang private GeoView? _geoView; private WeakEventListener? _geoViewBookmarksListener; private WeakEventListener? _geoViewLoadListener; - private new WeakEventListener? _overrideListListener; + private WeakEventListener? _overrideListListener; private IList? _overrideList; private IList ActiveBookmarkList From 1f2c020ff70cc8b70abc9e70f6bb0d987f0786fd Mon Sep 17 00:00:00 2001 From: Prathamesh Narkhede Date: Wed, 4 Sep 2024 16:46:45 -0700 Subject: [PATCH 08/10] Refactor BookmarksView for simplicity and performance --- .../BookmarksView/BookmarksView.cs | 42 +++++-------------- 1 file changed, 11 insertions(+), 31 deletions(-) diff --git a/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs b/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs index 59342b348..b428968ec 100644 --- a/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs +++ b/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs @@ -24,7 +24,7 @@ namespace Esri.ArcGISRuntime.Toolkit.Maui; /// public class BookmarksView : TemplatedView { - private BookmarksViewDataSource _dataSource = new BookmarksViewDataSource(); + private readonly BookmarksViewDataSource _dataSource = new(); private const string _presentingViewName = "PresentingView"; private static readonly DataTemplate DefaultDataTemplate; @@ -33,18 +33,17 @@ public class BookmarksView : TemplatedView [DynamicDependency(nameof(Bookmark.Name), "Esri.ArcGISRuntime.Mapping.Bookmark", "Esri.ArcGISRuntime")] static BookmarksView() { - DefaultDataTemplate = new DataTemplate(() => - { - var defaultLabel = new Label(); - defaultLabel.SetBinding(Label.TextProperty, nameof(Bookmark.Name)); - return defaultLabel; - }); + string dataTemplate = + @" + "; + DefaultDataTemplate = Microsoft.Maui.Controls.Xaml.Extensions.LoadFromXaml(new DataTemplate(), dataTemplate); string template = $@" - + xmlns:x=""http://schemas.microsoft.com/winfx/2009/xaml"" + xmlns:esriTK=""clr-namespace:Esri.ArcGISRuntime.Toolkit.Maui""> + "; DefaultControlTemplate = Microsoft.Maui.Controls.Xaml.Extensions.LoadFromXaml(new ControlTemplate(), template); } @@ -70,8 +69,8 @@ protected override void OnApplyTemplate() { view.SelectionChanged -= Internal_bookmarkSelected; view.SelectionChanged += Internal_bookmarkSelected; + view.ItemsSource = _dataSource; } - UpdatePresentingView(); } /// @@ -123,7 +122,7 @@ public GeoView? GeoView /// Identifies the bindable property. /// public static readonly BindableProperty ItemTemplateProperty = - BindableProperty.Create(nameof(ItemTemplate), typeof(DataTemplate), typeof(BookmarksView), DefaultDataTemplate, BindingMode.OneWay, null, propertyChanged: ItemTemplateChanged); + BindableProperty.Create(nameof(ItemTemplate), typeof(DataTemplate), typeof(BookmarksView), DefaultDataTemplate, BindingMode.OneWay, null); /// /// Handles property changes for the bindable property. @@ -143,15 +142,6 @@ private static void GeoViewChanged(BindableObject sender, object? oldValue, obje bookmarkView._dataSource.SetGeoView(newValue as GeoView); } - /// - /// Handles property changes for the bindable property. - /// - private static void ItemTemplateChanged(BindableObject sender, object? oldValue, object? newValue) - { - BookmarksView bookmarksView = (BookmarksView)sender; - bookmarksView.UpdatePresentingView(); - } - /// /// Selects the bookmark and navigates to it in the associated . /// @@ -184,16 +174,6 @@ private void Internal_bookmarkSelected(object? sender, SelectionChangedEventArgs } } - private void UpdatePresentingView() - { - var collectionView = (CollectionView)GetTemplateChild(_presentingViewName); - if (collectionView is CollectionView view) - { - view.ItemTemplate = ItemTemplate; - view.ItemsSource = _dataSource; - } - } - /// /// Raised whenever a bookmark is selected. /// From 5d2ffa0ca9f13b936aa1657b09285d05cdc11b94 Mon Sep 17 00:00:00 2001 From: Prathamesh Narkhede Date: Wed, 4 Sep 2024 17:00:31 -0700 Subject: [PATCH 09/10] Refactor BookmarksView to use class-level CollectionView to maintain sequence of detaching and attaching events --- .../Toolkit.Maui/BookmarksView/BookmarksView.cs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs b/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs index b428968ec..ec96c8f5d 100644 --- a/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs +++ b/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs @@ -26,6 +26,7 @@ public class BookmarksView : TemplatedView { private readonly BookmarksViewDataSource _dataSource = new(); private const string _presentingViewName = "PresentingView"; + CollectionView? _presentingView; private static readonly DataTemplate DefaultDataTemplate; private static readonly ControlTemplate DefaultControlTemplate; @@ -64,12 +65,16 @@ protected override void OnApplyTemplate() { base.OnApplyTemplate(); - var collectionView = (CollectionView)GetTemplateChild(_presentingViewName); - if (collectionView is CollectionView view) + if (_presentingView is not null) { - view.SelectionChanged -= Internal_bookmarkSelected; - view.SelectionChanged += Internal_bookmarkSelected; - view.ItemsSource = _dataSource; + _presentingView.SelectionChanged -= Internal_bookmarkSelected; + } + + if (GetTemplateChild(_presentingViewName) is CollectionView view) + { + _presentingView = view; + _presentingView.SelectionChanged += Internal_bookmarkSelected; + _presentingView.ItemsSource = _dataSource; } } From 8faf76eb8c9d3944a89783354aaf60f3719dadce Mon Sep 17 00:00:00 2001 From: Prathamesh Narkhede Date: Wed, 4 Sep 2024 17:50:03 -0700 Subject: [PATCH 10/10] Refactor _presentingView visibility and assignment logic --- src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs b/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs index ec96c8f5d..fafa741ee 100644 --- a/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs +++ b/src/Toolkit/Toolkit.Maui/BookmarksView/BookmarksView.cs @@ -26,7 +26,7 @@ public class BookmarksView : TemplatedView { private readonly BookmarksViewDataSource _dataSource = new(); private const string _presentingViewName = "PresentingView"; - CollectionView? _presentingView; + private CollectionView? _presentingView; private static readonly DataTemplate DefaultDataTemplate; private static readonly ControlTemplate DefaultControlTemplate; @@ -69,10 +69,9 @@ protected override void OnApplyTemplate() { _presentingView.SelectionChanged -= Internal_bookmarkSelected; } - - if (GetTemplateChild(_presentingViewName) is CollectionView view) + _presentingView = GetTemplateChild(_presentingViewName) as CollectionView; + if (_presentingView is not null) { - _presentingView = view; _presentingView.SelectionChanged += Internal_bookmarkSelected; _presentingView.ItemsSource = _dataSource; }