anagram4wander / VirtualizingObservableCollection

.NET PCL With Virtualizing Observable Collection
http://alphachitech.wordpress.com/2015/01/31/virtualizing-observable-collection/
56 stars 28 forks source link

Bug? CollectionChanged does not fire for all items in collection #7

Open dstarman99 opened 9 years ago

dstarman99 commented 9 years ago

It seems that the CollectionChanged event only fires for Visible items in the UI and not for all loaded items.

To replicate this issue in the sample project add the following to MainWindow.xaml.cs:

private void MyDataVirtualizedAsyncFilterSortObservableCollection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
    Console.WriteLine(((RemoteOrDbDataItem)e.NewItems[0]).Name);
}

Then add the following to the VirtualizingObservableCollection property:

_myDataVirtualizedAsyncFilterSortObservableCollection.CollectionChanged += MyDataVirtualizedAsyncFilterSortObservableCollection_CollectionChanged;

You will see that Output only includes visible items (1-15) and does not include the full loaded set (1-100). When you scroll to the next set (101-200), again only the items in view fire the CollectionChanged event.

How can I get notification for each item that has been added to the collection?

sgdowney commented 9 years ago

With this being a virtual collection, only the items required for viewing are actually retrieved. That's why the event only fires for the items in view. If you are not dealing with huge data sets then this may not be the appropriate collection type to use.

dstarman99 commented 9 years ago

Thank you for the response.

I do have large datasets (50,000+ records). The issue is that I need to know when items are loaded into the collection. The collection changed events only fire for the visible items when the collection is loaded from the itemsource. It renders the collection changed event useless during loading since you will only get change events on the initially visible items. When you scroll the list to see more visible items the event does not fire until you hit items that have not been loaded form the itemsource.

Example: Assumption: Data set size 1000+ records Assumption: ListView shows 10 items Upon loading the control ListView virtualization requests items 1-10. The ObservableCollection triggers the ItemSource to get the first page (100 items). CollectionChanged is fired for items 1-10. User scrolls to item 50. Items 50-60 are already loaded in the collection and are displayed. No CollectionChanged event occurs. User scrolls to item 120. Items 120-130 are not in the collection so they are retrieved from the ItemSource (page 2). CollectionChanged is fired for items 120-130. User scrolls to item 150. Items 150-160 are already loaded in the collection and are displayed. No CollectionChanged event occurs.

Essentially we have loaded 200 items into the collection and fired CollectionChanged events on just 20 items even though the user scrolled to see a total of 40 items. The desired behavior would be to have either CollectionChanged fire for all 200 items (preferred) or have CollectionChanged fire for items upon first-time view.

-Dave

From: Stewart Downey [mailto:notifications@github.com] Sent: Monday, August 31, 2015 9:48 AM To: anagram4wander/VirtualizingObservableCollection Cc: Dave Starman Subject: Re: [VirtualizingObservableCollection] Bug? CollectionChanged does not fire for all items in collection (#7)

With this being a virtual collection, only the items required for viewing are actually retrieved. That's why the event only fires for the items in view. If you are not dealing with huge data sets then this may not be the appropriate collection type to use.

— Reply to this email directly or view it on GitHubhttps://github.com/anagram4wander/VirtualizingObservableCollection/issues/7#issuecomment-136412141.

anagram4wander commented 9 years ago

Hi, I understand the issue - but the collection changed is optimized for large sets.

What are you hooking on collection changed ? The source provider or the ctor of the object might be a better place to do that - or in the view of the data template.. Via a behavior.

Sent from my iPhone

On Aug 31, 2015, at 10:36 AM, dstarman99 notifications@github.com wrote:

Thank you for the response.

I do have large datasets (50,000+ records). The issue is that I need to know when items are loaded into the collection. The collection changed events only fire for the visible items when the collection is loaded from the itemsource. It renders the collection changed event useless during loading since you will only get change events on the initially visible items. When you scroll the list to see more visible items the event does not fire until you hit items that have not been loaded form the itemsource.

Example: Assumption: Data set size 1000+ records Assumption: ListView shows 10 items Upon loading the control ListView virtualization requests items 1-10. The ObservableCollection triggers the ItemSource to get the first page (100 items). CollectionChanged is fired for items 1-10. User scrolls to item 50. Items 50-60 are already loaded in the collection and are displayed. No CollectionChanged event occurs. User scrolls to item 120. Items 120-130 are not in the collection so they are retrieved from the ItemSource (page 2). CollectionChanged is fired for items 120-130. User scrolls to item 150. Items 150-160 are already loaded in the collection and are displayed. No CollectionChanged event occurs.

Essentially we have loaded 200 items into the collection and fired CollectionChanged events on just 20 items even though the user scrolled to see a total of 40 items. The desired behavior would be to have either CollectionChanged fire for all 200 items (preferred) or have CollectionChanged fire for items upon first-time view.

-Dave

From: Stewart Downey [mailto:notifications@github.com] Sent: Monday, August 31, 2015 9:48 AM To: anagram4wander/VirtualizingObservableCollection Cc: Dave Starman Subject: Re: [VirtualizingObservableCollection] Bug? CollectionChanged does not fire for all items in collection (#7)

With this being a virtual collection, only the items required for viewing are actually retrieved. That's why the event only fires for the items in view. If you are not dealing with huge data sets then this may not be the appropriate collection type to use.

— Reply to this email directly or view it on GitHubhttps://github.com/anagram4wander/VirtualizingObservableCollection/issues/7#issuecomment-136412141. — Reply to this email directly or view it on GitHub.

dstarman99 commented 9 years ago

I was using the ObservableCollection and needed to know when properties of loaded collection items changed. I wired the item changed event to the object through the CollectionChanged event. This Stackoverflow question explains it well: http://stackoverflow.com/questions/1427471/observablecollection-not-noticing-when-item-in-it-changes-even-with-inotifyprop

Creating the event reference through the source provider would resolve the problem. Thank you for taking the time to address the issue; you’ve put together a very useful collection.

From: anagram4wander [mailto:notifications@github.com] Sent: Monday, August 31, 2015 11:41 AM To: anagram4wander/VirtualizingObservableCollection Cc: Dave Starman Subject: Re: [VirtualizingObservableCollection] Bug? CollectionChanged does not fire for all items in collection (#7)

Hi, I understand the issue - but the collection changed is optimized for large sets.

What are you hooking on collection changed ? The source provider or the ctor of the object might be a better place to do that - or in the view of the data template.. Via a behavior.

Sent from my iPhone

On Aug 31, 2015, at 10:36 AM, dstarman99 notifications@github.com<mailto:notifications@github.com> wrote:

Thank you for the response.

I do have large datasets (50,000+ records). The issue is that I need to know when items are loaded into the collection. The collection changed events only fire for the visible items when the collection is loaded from the itemsource. It renders the collection changed event useless during loading since you will only get change events on the initially visible items. When you scroll the list to see more visible items the event does not fire until you hit items that have not been loaded form the itemsource.

Example: Assumption: Data set size 1000+ records Assumption: ListView shows 10 items Upon loading the control ListView virtualization requests items 1-10. The ObservableCollection triggers the ItemSource to get the first page (100 items). CollectionChanged is fired for items 1-10. User scrolls to item 50. Items 50-60 are already loaded in the collection and are displayed. No CollectionChanged event occurs. User scrolls to item 120. Items 120-130 are not in the collection so they are retrieved from the ItemSource (page 2). CollectionChanged is fired for items 120-130. User scrolls to item 150. Items 150-160 are already loaded in the collection and are displayed. No CollectionChanged event occurs.

Essentially we have loaded 200 items into the collection and fired CollectionChanged events on just 20 items even though the user scrolled to see a total of 40 items. The desired behavior would be to have either CollectionChanged fire for all 200 items (preferred) or have CollectionChanged fire for items upon first-time view.

-Dave

From: Stewart Downey [mailto:notifications@github.com] Sent: Monday, August 31, 2015 9:48 AM To: anagram4wander/VirtualizingObservableCollection Cc: Dave Starman Subject: Re: [VirtualizingObservableCollection] Bug? CollectionChanged does not fire for all items in collection (#7)

With this being a virtual collection, only the items required for viewing are actually retrieved. That's why the event only fires for the items in view. If you are not dealing with huge data sets then this may not be the appropriate collection type to use.

— Reply to this email directly or view it on GitHubhttps://github.com/anagram4wander/VirtualizingObservableCollection/issues/7#issuecomment-136412141. — Reply to this email directly or view it on GitHub.

— Reply to this email directly or view it on GitHubhttps://github.com/anagram4wander/VirtualizingObservableCollection/issues/7#issuecomment-136440417.

anagram4wander commented 9 years ago

If it was me - I would put a behavior inside the datatemplate - that way you can unwire on detaching as well (you will have to hook on data context changed not just attaching / detaching assuming you are recycling). Unless your event is weak it's going to leak..

Sent from my iPhone

On Aug 31, 2015, at 11:32 AM, dstarman99 notifications@github.com wrote:

I was using the ObservableCollection and needed to know when properties of loaded collection items changed. I wired the item changed event to the object through the CollectionChanged event. This Stackoverflow question explains it well: http://stackoverflow.com/questions/1427471/observablecollection-not-noticing-when-item-in-it-changes-even-with-inotifyprop

Creating the event reference through the source provider would resolve the problem. Thank you for taking the time to address the issue; you’ve put together a very useful collection.

From: anagram4wander [mailto:notifications@github.com] Sent: Monday, August 31, 2015 11:41 AM To: anagram4wander/VirtualizingObservableCollection Cc: Dave Starman Subject: Re: [VirtualizingObservableCollection] Bug? CollectionChanged does not fire for all items in collection (#7)

Hi, I understand the issue - but the collection changed is optimized for large sets.

What are you hooking on collection changed ? The source provider or the ctor of the object might be a better place to do that - or in the view of the data template.. Via a behavior.

Sent from my iPhone

On Aug 31, 2015, at 10:36 AM, dstarman99 notifications@github.com<mailto:notifications@github.com> wrote:

Thank you for the response.

I do have large datasets (50,000+ records). The issue is that I need to know when items are loaded into the collection. The collection changed events only fire for the visible items when the collection is loaded from the itemsource. It renders the collection changed event useless during loading since you will only get change events on the initially visible items. When you scroll the list to see more visible items the event does not fire until you hit items that have not been loaded form the itemsource.

Example: Assumption: Data set size 1000+ records Assumption: ListView shows 10 items Upon loading the control ListView virtualization requests items 1-10. The ObservableCollection triggers the ItemSource to get the first page (100 items). CollectionChanged is fired for items 1-10. User scrolls to item 50. Items 50-60 are already loaded in the collection and are displayed. No CollectionChanged event occurs. User scrolls to item 120. Items 120-130 are not in the collection so they are retrieved from the ItemSource (page 2). CollectionChanged is fired for items 120-130. User scrolls to item 150. Items 150-160 are already loaded in the collection and are displayed. No CollectionChanged event occurs.

Essentially we have loaded 200 items into the collection and fired CollectionChanged events on just 20 items even though the user scrolled to see a total of 40 items. The desired behavior would be to have either CollectionChanged fire for all 200 items (preferred) or have CollectionChanged fire for items upon first-time view.

-Dave

From: Stewart Downey [mailto:notifications@github.com] Sent: Monday, August 31, 2015 9:48 AM To: anagram4wander/VirtualizingObservableCollection Cc: Dave Starman Subject: Re: [VirtualizingObservableCollection] Bug? CollectionChanged does not fire for all items in collection (#7)

With this being a virtual collection, only the items required for viewing are actually retrieved. That's why the event only fires for the items in view. If you are not dealing with huge data sets then this may not be the appropriate collection type to use.

— Reply to this email directly or view it on GitHubhttps://github.com/anagram4wander/VirtualizingObservableCollection/issues/7#issuecomment-136412141. — Reply to this email directly or view it on GitHub.

— Reply to this email directly or view it on GitHubhttps://github.com/anagram4wander/VirtualizingObservableCollection/issues/7#issuecomment-136440417. — Reply to this email directly or view it on GitHub.