xamarin / Xamarin.Forms

Xamarin.Forms is no longer supported. Migrate your apps to .NET MAUI.
https://aka.ms/xamarin-upgrade
Other
5.62k stars 1.87k forks source link

[Bug] CollectionView Redundant Binding #12202

Open aeonblaire opened 4 years ago

aeonblaire commented 4 years ago

Description

CollectionView sets ItemSource objects as BindingContext of multiple Views created thru the ItemTemplate in initial binding of ItemSource, adding and removing items in ItemSource. EDIT: It seems that CollectionView is [pre]caching item views but many are unnecessarily assigned their binding context to existing objects in ItemSource.

Steps to Reproduce

Observe the Debug output in initial binding, adding and removing items in the sample project.

Expected Behavior

Objects from ItemSource is set as binding context for only a single item view instantiated from ItemTemplate (or reused from cache) within the CollectionView. When an object is removed from ItemSource, the binding context of the corresponding item view should be set to null.

Actual Behavior

ItemSource objects are set as BindingContext of multiple Views created thru the ItemTemplate in initial binding of ItemSource, adding and removing items in ItemSource. When an object is removed from ItemSource, the binding context of the corresponding item view is not set to null.

Basic Information

rmarinho commented 4 years ago

Sorry but i m not understanding the question , can you explain a little better, for example what do you expect the output to be when add remove items. right now i see this and it looks fine:

[0:] Item 82af7ee6-ec43-4dc4-a5d3-ca618a5a2d73 was added.
[0:] Item 82af7ee6-ec43-4dc4-a5d3-ca618a5a2d73 was binded to ItemView 9d1f32f4-9d0f-4b0b-857c-990583d1ae1a
[0:] Item 82af7ee6-ec43-4dc4-a5d3-ca618a5a2d73 was removed.
[0:] ItemView 9d1f32f4-9d0f-4b0b-857c-990583d1ae1a binding context was set to null.
[0:] Item d8385c59-ceac-4e6d-9573-14d3fd52d184 was added.
[0:] Item d8385c59-ceac-4e6d-9573-14d3fd52d184 was binded to ItemView 9d1f32f4-9d0f-4b0b-857c-990583d1ae1a
[0:] Item d947777f-aba4-4981-a2af-8ea08bda45b0 was added.
[0:] Item d947777f-aba4-4981-a2af-8ea08bda45b0 was binded to ItemView db59452d-f294-422f-948a-b78224596eec
aeonblaire commented 4 years ago

This is what I get:

[ First Run, initial item count of 2 ] Item 54cf76d6-5aaf-450f-850d-8cfe863aec79 was binded to ItemView ba638e84-d397-4b2e-b873-67d7b07a5663 Item 54cf76d6-5aaf-450f-850d-8cfe863aec79 was binded to ItemView 892f1063-e8eb-42a3-97da-05e5caa8f98e Item 54cf76d6-5aaf-450f-850d-8cfe863aec79 was binded to ItemView 50f2f709-debe-47d6-a706-d32602897b33 Item 27896b06-52db-44d5-8c02-957a994cf2a5 was binded to ItemView d7b4f4a1-1f7a-4e98-bc78-150ad0c9e075

[ Remove Second Item ] Item 54cf76d6-5aaf-450f-850d-8cfe863aec79 was binded to ItemView 5ee76aa4-cc55-4087-a755-9dee2b709f2d Item 27896b06-52db-44d5-8c02-957a994cf2a5 was removed.

[ Remove remaining Item ] Item 54cf76d6-5aaf-450f-850d-8cfe863aec79 was removed.

[ Add an Item ] Item fa6b8e51-ccea-4f8a-b0dc-f650c5dfb75e was added. Item fa6b8e51-ccea-4f8a-b0dc-f650c5dfb75e was binded to ItemView 50f2f709-debe-47d6-a706-d32602897b33 Item fa6b8e51-ccea-4f8a-b0dc-f650c5dfb75e was binded to ItemView d7b4f4a1-1f7a-4e98-bc78-150ad0c9e075

[ Add next Item ] Item 4aebb0f0-5228-47d4-a9aa-3a822eb1e125 was binded to ItemView 5ee76aa4-cc55-4087-a755-9dee2b709f2d Item fa6b8e51-ccea-4f8a-b0dc-f650c5dfb75e was binded to ItemView 5ee76aa4-cc55-4087-a755-9dee2b709f2d Item 4aebb0f0-5228-47d4-a9aa-3a822eb1e125 was binded to ItemView 5ee76aa4-cc55-4087-a755-9dee2b709f2d Item 4aebb0f0-5228-47d4-a9aa-3a822eb1e125 was added.

EDIT: It seems that CollectionView is [pre]caching item views but many are unnecessarily assigned their binding context to existing objects in ItemSource.

aeonblaire commented 4 years ago

I tried on Android and it functions as expected, no unnecessary setting of the binding context, and it even sets to null when the corresponding object is removed from ItemSource. Any ideas?

aeonblaire commented 4 years ago

I found a clue here: https://github.com/xamarin/Xamarin.Forms/issues/7152#issuecomment-521659578

StephaneDelcroix commented 4 years ago

When an object is removed from ItemSource, the binding context of the corresponding item view is not set to null.

this might be worth investigating, @hartez

Lakshminatarajan commented 2 years ago

We are also experiencing the same problem. In the CollectionView's ItemTemplate, we're using custom layout (e.g., FlexLayout). When we update the ItemsSource at runtime, the old items binding is not disposed of or set to null. As a result, our layout duplicated in the view.

If we set the BindingContext of the removed items to null, the binding issue may be resolved.

However, the old items are maintained in memory. The custom layout object grew in memory with each update of ItemsSource.