From b774718a8baacdedaa8234f1f143743a77756251 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thomas?= Date: Mon, 22 Dec 2025 16:07:36 +0100 Subject: [PATCH 1/4] Implement DatatemplateSelector support on DragDropGridView.Itemsource --- .../DragDropGridView.Drag.Utilities.cs | 27 +++--- .../DragDropGridView.ItemsSource.cs | 92 +++++++++++++------ 2 files changed, 75 insertions(+), 44 deletions(-) diff --git a/DragDropGridView/DragDropGridView.Drag.Utilities.cs b/DragDropGridView/DragDropGridView.Drag.Utilities.cs index 0faefe5..b9974b8 100644 --- a/DragDropGridView/DragDropGridView.Drag.Utilities.cs +++ b/DragDropGridView/DragDropGridView.Drag.Utilities.cs @@ -9,22 +9,19 @@ public partial class DragDropGridView private void UpdateDisableScrollView(bool isDisabled) { #if ANDROID - if (_scrollView != null) - { - InternalLogger.Debug(Tag, () => $"UpdateScrollView( disabled: {isDisabled} )"); - ((UntouchableScrollviewHandler)_scrollView.Handler!).UpdateDisableScrolling(isDisabled); - } + if (_scrollView?.Handler is UntouchableScrollviewHandler scrollHandler && + scrollHandler.PlatformView != null) + { + InternalLogger.Debug(Tag, () => $"UpdateScrollView( disabled: {isDisabled} )"); + scrollHandler.UpdateDisableScrolling(isDisabled); + } - if (_refreshView != null) - { - InternalLogger.Debug(Tag, () => $"UpdateRefreshView( disabled: {isDisabled} )"); - ((UntouchableRefreshViewHandler)_refreshView.Handler!).UpdateDisableScrolling(isDisabled); - } -#elif !WINDOWS - if (_scrollView != null) - { - _scrollView.IsEnabled = !isDisabled; - } + if (_refreshView?.Handler is UntouchableRefreshViewHandler refreshHandler && + refreshHandler.PlatformView != null) + { + InternalLogger.Debug(Tag, () => $"UpdateRefreshView( disabled: {isDisabled} )"); + refreshHandler.UpdateDisableScrolling(isDisabled); + } #endif } diff --git a/DragDropGridView/DragDropGridView.ItemsSource.cs b/DragDropGridView/DragDropGridView.ItemsSource.cs index c7a49d7..340aca6 100644 --- a/DragDropGridView/DragDropGridView.ItemsSource.cs +++ b/DragDropGridView/DragDropGridView.ItemsSource.cs @@ -19,6 +19,13 @@ public partial class DragDropGridView default(DataTemplate), propertyChanged: OnItemTemplateChanged); + public static readonly BindableProperty ItemTemplateSelectorProperty = BindableProperty.Create( + nameof(ItemTemplateSelector), + typeof(DataTemplateSelector), + typeof(DragDropGridView), + default(DataTemplateSelector), + propertyChanged: OnItemTemplateSelectorChanged); + public IEnumerable ItemsSource { get => (IEnumerable)GetValue(ItemsSourceProperty); @@ -31,6 +38,12 @@ public DataTemplate ItemTemplate set => SetValue(ItemTemplateProperty, value); } + public DataTemplateSelector ItemTemplateSelector + { + get => (DataTemplateSelector)GetValue(ItemTemplateSelectorProperty); + set => SetValue(ItemTemplateSelectorProperty, value); + } + private static void OnItemsSourceChanged(BindableObject bindable, object? oldValue, object? newValue) { if (bindable is not DragDropGridView gridLayout) @@ -52,7 +65,7 @@ private static void OnItemsSourceChanged(BindableObject bindable, object? oldVal foreach (var item in (IEnumerable)newValue) { - if (gridLayout.ItemTemplate.CreateContent() is not View view) + if (gridLayout.GetTemplateForItem(item).CreateContent() is not View view) { continue; } @@ -69,34 +82,12 @@ private static void OnItemsSourceChanged(BindableObject bindable, object? oldVal private static void OnItemTemplateChanged(BindableObject bindable, object oldValue, object newValue) { - if (bindable is not DragDropGridView gridLayout) - { - return; - } - - gridLayout.Clear(); - - if (gridLayout.ItemsSource is null) - { - return; - } - - if (gridLayout.ItemsSource is INotifyCollectionChanged notifyCollection) - { - notifyCollection.CollectionChanged -= gridLayout.ItemsSourceCollectionChanged; - notifyCollection.CollectionChanged += gridLayout.ItemsSourceCollectionChanged; - } - - foreach (var item in gridLayout.ItemsSource) - { - if (gridLayout.ItemTemplate.CreateContent() is not View view) - { - continue; - } + RebuildChildren(bindable); + } - view.BindingContext = item; - gridLayout.Children.Add(view); - } + private static void OnItemTemplateSelectorChanged(BindableObject bindable, object oldValue, object newValue) + { + RebuildChildren(bindable); } private void ItemsSourceCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) @@ -111,7 +102,7 @@ private void ItemsSourceCollectionChanged(object? sender, NotifyCollectionChange case NotifyCollectionChangedAction.Add when e.NewItems is not null: foreach (var item in e.NewItems) { - if (ItemTemplate.CreateContent() is not View view) + if (GetTemplateForItem(item).CreateContent() is not View view) { continue; } @@ -155,5 +146,48 @@ private void ItemsSourceCollectionChanged(object? sender, NotifyCollectionChange default: throw new ArgumentOutOfRangeException(); } + + } + + private DataTemplate GetTemplateForItem(object item) + { + if (ItemTemplateSelector != null) + { + var test = ItemTemplateSelector.SelectTemplate(item, this); + return test; + } + return ItemTemplate; + } + + private static void RebuildChildren(BindableObject bindable) + { + if (bindable is not DragDropGridView gridLayout) + { + return; + } + + gridLayout.Clear(); + + if (gridLayout.ItemsSource is null) + { + return; + } + + if (gridLayout.ItemsSource is INotifyCollectionChanged notifyCollection) + { + notifyCollection.CollectionChanged -= gridLayout.ItemsSourceCollectionChanged; + notifyCollection.CollectionChanged += gridLayout.ItemsSourceCollectionChanged; + } + + foreach (var item in gridLayout.ItemsSource) + { + if (gridLayout.GetTemplateForItem(item).CreateContent() is not View view) + { + continue; + } + + view.BindingContext = item; + gridLayout.Children.Add(view); + } } } \ No newline at end of file From c65738af976d5fb7e08b2d371c13a0b6a1281e32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thomas?= Date: Mon, 22 Dec 2025 19:11:49 +0100 Subject: [PATCH 2/4] Add Nullable checks and remove test variable --- DragDropGridView/DragDropGridView.ItemsSource.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/DragDropGridView/DragDropGridView.ItemsSource.cs b/DragDropGridView/DragDropGridView.ItemsSource.cs index 340aca6..31ba51b 100644 --- a/DragDropGridView/DragDropGridView.ItemsSource.cs +++ b/DragDropGridView/DragDropGridView.ItemsSource.cs @@ -65,7 +65,7 @@ private static void OnItemsSourceChanged(BindableObject bindable, object? oldVal foreach (var item in (IEnumerable)newValue) { - if (gridLayout.GetTemplateForItem(item).CreateContent() is not View view) + if (gridLayout.GetTemplateForItem(item)?.CreateContent() is not View view) { continue; } @@ -102,7 +102,7 @@ private void ItemsSourceCollectionChanged(object? sender, NotifyCollectionChange case NotifyCollectionChangedAction.Add when e.NewItems is not null: foreach (var item in e.NewItems) { - if (GetTemplateForItem(item).CreateContent() is not View view) + if (GetTemplateForItem(item)?.CreateContent() is not View view) { continue; } @@ -153,8 +153,7 @@ private DataTemplate GetTemplateForItem(object item) { if (ItemTemplateSelector != null) { - var test = ItemTemplateSelector.SelectTemplate(item, this); - return test; + return ItemTemplateSelector.SelectTemplate(item, this); } return ItemTemplate; } @@ -181,7 +180,7 @@ private static void RebuildChildren(BindableObject bindable) foreach (var item in gridLayout.ItemsSource) { - if (gridLayout.GetTemplateForItem(item).CreateContent() is not View view) + if (gridLayout.GetTemplateForItem(item)?.CreateContent() is not View view) { continue; } From 5e7c520752b2bea51704ec0ff0cd358f3da603b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thomas?= Date: Mon, 22 Dec 2025 19:20:55 +0100 Subject: [PATCH 3/4] Add back Windows check for ScrollView IsEnabled. --- DragDropGridView/DragDropGridView.Drag.Utilities.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/DragDropGridView/DragDropGridView.Drag.Utilities.cs b/DragDropGridView/DragDropGridView.Drag.Utilities.cs index b9974b8..35f1c75 100644 --- a/DragDropGridView/DragDropGridView.Drag.Utilities.cs +++ b/DragDropGridView/DragDropGridView.Drag.Utilities.cs @@ -22,6 +22,11 @@ private void UpdateDisableScrollView(bool isDisabled) InternalLogger.Debug(Tag, () => $"UpdateRefreshView( disabled: {isDisabled} )"); refreshHandler.UpdateDisableScrolling(isDisabled); } +#elif !WINDOWS + if (_scrollView != null) + { + _scrollView.IsEnabled = !isDisabled; + } #endif } From 51efab3aaec301ac7167d8e0e9db9d6b2fa3ec91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thomas?= Date: Wed, 31 Dec 2025 07:05:30 +0100 Subject: [PATCH 4/4] Refact code: The refactoring involved consolidating the property change handlers for ItemTemplate and ItemTemplateSelector into a single OnItemTemplateChanged(BindableObject, object, object) method. This was unnecessary to create a separate handler for ItemTemplateSelector, as the shared handler already handles both cases by reloading items and using GetTemplateForItem(object) to select the appropriate template (via selector if present, otherwise the direct template). This reduces code duplication and maintains the same functionality. --- .../DragDropGridView.ItemsSource.cs | 66 ++++++++----------- 1 file changed, 28 insertions(+), 38 deletions(-) diff --git a/DragDropGridView/DragDropGridView.ItemsSource.cs b/DragDropGridView/DragDropGridView.ItemsSource.cs index 31ba51b..fcb6883 100644 --- a/DragDropGridView/DragDropGridView.ItemsSource.cs +++ b/DragDropGridView/DragDropGridView.ItemsSource.cs @@ -24,7 +24,7 @@ public partial class DragDropGridView typeof(DataTemplateSelector), typeof(DragDropGridView), default(DataTemplateSelector), - propertyChanged: OnItemTemplateSelectorChanged); + propertyChanged: OnItemTemplateChanged); public IEnumerable ItemsSource { @@ -82,12 +82,34 @@ private static void OnItemsSourceChanged(BindableObject bindable, object? oldVal private static void OnItemTemplateChanged(BindableObject bindable, object oldValue, object newValue) { - RebuildChildren(bindable); - } + if (bindable is not DragDropGridView gridLayout) + { + return; + } - private static void OnItemTemplateSelectorChanged(BindableObject bindable, object oldValue, object newValue) - { - RebuildChildren(bindable); + gridLayout.Clear(); + + if (gridLayout.ItemsSource is null) + { + return; + } + + if (gridLayout.ItemsSource is INotifyCollectionChanged notifyCollection) + { + notifyCollection.CollectionChanged -= gridLayout.ItemsSourceCollectionChanged; + notifyCollection.CollectionChanged += gridLayout.ItemsSourceCollectionChanged; + } + + foreach (var item in gridLayout.ItemsSource) + { + if (gridLayout.GetTemplateForItem(item)?.CreateContent() is not View view) + { + continue; + } + + view.BindingContext = item; + gridLayout.Children.Add(view); + } } private void ItemsSourceCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) @@ -157,36 +179,4 @@ private DataTemplate GetTemplateForItem(object item) } return ItemTemplate; } - - private static void RebuildChildren(BindableObject bindable) - { - if (bindable is not DragDropGridView gridLayout) - { - return; - } - - gridLayout.Clear(); - - if (gridLayout.ItemsSource is null) - { - return; - } - - if (gridLayout.ItemsSource is INotifyCollectionChanged notifyCollection) - { - notifyCollection.CollectionChanged -= gridLayout.ItemsSourceCollectionChanged; - notifyCollection.CollectionChanged += gridLayout.ItemsSourceCollectionChanged; - } - - foreach (var item in gridLayout.ItemsSource) - { - if (gridLayout.GetTemplateForItem(item)?.CreateContent() is not View view) - { - continue; - } - - view.BindingContext = item; - gridLayout.Children.Add(view); - } - } } \ No newline at end of file