diff --git a/samples/CommunityToolkit.Maui.Sample/Pages/Behaviors/TouchBehaviorPage.xaml b/samples/CommunityToolkit.Maui.Sample/Pages/Behaviors/TouchBehaviorPage.xaml
index 09357a500..8f1b88ea8 100644
--- a/samples/CommunityToolkit.Maui.Sample/Pages/Behaviors/TouchBehaviorPage.xaml
+++ b/samples/CommunityToolkit.Maui.Sample/Pages/Behaviors/TouchBehaviorPage.xaml
@@ -25,7 +25,6 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/CommunityToolkit.Maui.Sample/ViewModels/Behaviors/ItemViewModel.cs b/samples/CommunityToolkit.Maui.Sample/ViewModels/Behaviors/ItemViewModel.cs
new file mode 100644
index 000000000..3316dd7fb
--- /dev/null
+++ b/samples/CommunityToolkit.Maui.Sample/ViewModels/Behaviors/ItemViewModel.cs
@@ -0,0 +1,19 @@
+using CommunityToolkit.Mvvm.Input;
+
+namespace CommunityToolkit.Maui.Sample.ViewModels.Behaviors;
+
+public partial class ItemViewModel : BaseViewModel
+{
+ public string Title { get; }
+
+ public ItemViewModel(string title)
+ {
+ Title = title;
+ }
+
+ [RelayCommand]
+ public Task TapAsync()
+ {
+ return Application.Current?.MainPage?.DisplayAlert("Tap", Title, "OK") ?? Task.CompletedTask;
+ }
+}
\ No newline at end of file
diff --git a/samples/CommunityToolkit.Maui.Sample/ViewModels/Behaviors/TouchBehaviorViewModel.cs b/samples/CommunityToolkit.Maui.Sample/ViewModels/Behaviors/TouchBehaviorViewModel.cs
index b2adb9a24..706ce4c3e 100644
--- a/samples/CommunityToolkit.Maui.Sample/ViewModels/Behaviors/TouchBehaviorViewModel.cs
+++ b/samples/CommunityToolkit.Maui.Sample/ViewModels/Behaviors/TouchBehaviorViewModel.cs
@@ -1,3 +1,4 @@
+using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
@@ -7,6 +8,8 @@ public partial class TouchBehaviorViewModel : BaseViewModel
{
[ObservableProperty]
int touchCount, longPressCount;
+
+ public ObservableCollection Items { get; }
static Task DisplayAlert(string title, CancellationToken token)
=> Shell.Current.DisplayAlert(title, null, "Ok").WaitAsync(token);
@@ -19,6 +22,15 @@ static Task ParentClicked(CancellationToken token)
static Task ChildClicked(CancellationToken token)
=> DisplayAlert("Child Clicked", token);
+ public TouchBehaviorViewModel()
+ {
+ Items = [];
+ for (var i = 0; i < 50; ++i)
+ {
+ Items.Add(new ItemViewModel($"Item {i}"));
+ }
+ }
+
[RelayCommand]
async Task MonkeySelected(string? monkey, CancellationToken token)
{
@@ -42,4 +54,4 @@ void IncreaseLongPressCount()
{
LongPressCount++;
}
-}
\ No newline at end of file
+}
diff --git a/src/CommunityToolkit.Maui/Behaviors/ICommunityToolkitBehavior.shared.cs b/src/CommunityToolkit.Maui/Behaviors/ICommunityToolkitBehavior.shared.cs
index 0df155889..d81a2988d 100644
--- a/src/CommunityToolkit.Maui/Behaviors/ICommunityToolkitBehavior.shared.cs
+++ b/src/CommunityToolkit.Maui/Behaviors/ICommunityToolkitBehavior.shared.cs
@@ -21,11 +21,40 @@ internal bool TrySetBindingContextToAttachedViewBindingContext()
throw new InvalidOperationException($"{nameof(ICommunityToolkitBehavior)} can only be used for a {nameof(Behavior)}");
}
- if (behavior.IsSet(BindableObject.BindingContextProperty) || View is null)
+ if (View is null)
{
return false;
}
+ var parent = View.Parent;
+ var assignBindingContext = behavior.IsSet(BindableObject.BindingContextProperty) is false;
+
+ // If we have a BindingContext, the type is the same as the Views BindingContext and we are inside a CollectionView
+ // then we can assume that we are recycling views and need to assign the BindingContext again.
+ if (View.BindingContext?.GetType() == behavior.BindingContext?.GetType())
+ {
+ for (var i = 0; i < 10; i++)
+ {
+ if (parent is null)
+ {
+ break;
+ }
+
+ if (parent is CollectionView)
+ {
+ assignBindingContext = true;
+ break;
+ }
+
+ parent = parent.Parent;
+ }
+ }
+
+ if (assignBindingContext is false)
+ {
+ return false;
+ }
+
behavior.SetBinding(BindableObject.BindingContextProperty, new Binding
{
Source = View,
@@ -33,7 +62,6 @@ internal bool TrySetBindingContextToAttachedViewBindingContext()
});
return true;
-
}
internal bool TryRemoveBindingContext()