Open gonz01d opened 4 years ago
Looks like my issue could be a duplicate of / related to this one: https://github.com/xamarin/Xamarin.Forms/issues/9365
Thank you for pointing out the duplicate @gonz01d !!
I also tried setting ItemSizingStrategy="MeasureAllItems"
but the same issue surfaces
Thank you for pointing out the duplicate @gonz01d !!
I also tried setting
ItemSizingStrategy="MeasureAllItems"
but the same issue surfaces
No worries @PureWeen
I concur and probably should have mentioned that when I created the issue. I think MeasureAllItems
is the default ItemSizingStrategy
anyways but as you say even setting it explicitly makes no difference
Hey @gonz01d , I never fixed my issue, so I changed how my app behaved from expanding the views within the CollectionView to popping up a modal with a transparent grey background and featuring the view that was tapped in its expanded state. This way, the views in the CollectionView remain untouched in terms of layout and size, which is probably better for performance anyways.
Hope you find this suggestion helpful, otherwise I hope you find a solution to this problem.
same problem but with just dynamic resized items while loading the data (simple XAML with Binding a Text that can have multiple lines... in my real world case i have more complex layout but it can be reproduced very simple - see attached project)
After loading the data, item spacing is of if you scroll a bit - everything is corrected if you reload the data - problem occurs again
didn't happen on Android but only on ios as far as i can see
(Update) If you take my sample, you can remove the Binding Text from the xaml. Instead: Let the EntryCell show three lines of fixed text, for example in a grid - same problem! So even with fixed XAML this problem occures!
EntryCell fixed layout showing the same Problem:
`
Not sure if it's exactly the same as above, but I'm getting some strange issues with the CollectionView view recycling too. (This also occurs on a ListView with CachingStrategy set to RecycleElement).
Inserting a new item in to the bound observable collection causes some items below to loose their content. If you scroll pasts these items with the missing content, and then scroll back up to them, them content reappears.
Additionally with a ListView if you expand the height of the content of a ViewCell (by settings some content within it to IsVisible=True), the content of the ViewCell gets squished and the ViewCell does not increase it's height. Again, scroll away and come back and it's fine.
Hitting this same issue with a basic dynamic load of a string that could be multiple lines. Everything resizes correctly on the first scroll. Are there any suggested workarounds for this issue? (And I should mentioned that I switched away from using a ListView since I was having similar problems there so I don't view that as a valid workaround).
CollectionView also has the same issue => when first row is resized dynamically, the subsequent other rows get resized with first. Collection view has to reload technically and expand for the first cell or row. Forms version 4.5.0.617. Please can anybody update the status. This behaviour is common in ios. @samhouts
Another thing noted here is the moment i scroll the collection view it resizes properly. size is adjusted for all the other rows. Looks like the view is not reloading as expected.
CollectionView_sizing_issue.zip I even tried the preview version - None has the fix. The item dynamic size is copied to the later items and when we scroll the list the size is getting corrected. I have attached the sample of the same.
any indication when this is scheduled to be fixed? (or at least a work-around in the meantime) I see the 5.0 milestone target was removed?
It is very confusing when they keep adding and removing moving flags. "high impact" then it's not. In sprint x, then y, then "continue in sprint z" suggesting work had been started. The back to todo, then in 5.0, then removed from 5.0.
I think xamarin devs are getting tired. My company is getting tired and is looking at ditching xamarin all together and go native. There really needs to be some priority on fixing issues over releasing more half baked feature.
Critical Issue - still not getting attention? It's been almost a year now. @PureWeen @samhouts pretty please raise the priority on this guy.
I have the same issue with the background color set dynamically with a converter based on a property of the item (only some items needs another background color. When scrolling, the same color pattern is showing up again even the property has another value for that item.
Hi, can I know what year is it now? I've been travelling back and forth in time!
Anyway is this still an issue? Thanks guys for the reply
Is this issue going to be fixed soon, if at all? The same problem happens with other visual elements in the cell such as text decorations. Not having cells show incorrect data is literally the bare minimum I would expect from a list component like CollectionView...
if anyone has found a work-around for this issue, please post?
if anyone has found a work-around for this issue, please post?
If it helps my workaround was to switch back to the ListView
(with a tweak for iOS) - see my original post Workaround text for more detail : https://github.com/xamarin/Xamarin.Forms/issues/9520#issue-563212616
I'm starting to wonder if I made a mistake choosing Xamarin..
@gonz01d Correct me if I'm wrong but ListView only supports Vertical orientation right? So I wouldn't be able to use your fix in my case.
Hi, I just had a look at this.......This is not a Xamarin issue, it is the issue of not understanding how Collection Views Work.
Collection view repeats the item after a while based on the data template.
You must not change the size or color of the data template element directly as this will effect all elements.
If you intend to do something like changing color or size, bind the size and color to a view model of the item.
I can confirm that this issue can be closed. It works fine.
Updated Sample on how to implement this => CollectionViewCellResize UPDATED.zip
@azrinsani - dude, no! it cannot be closed :/
If you have a layout where you simple don't know the final size, the rows/cells should be able to resize themselfs.
In Short: I binding the size is your solution - maybe you have a great solution how to get the (dynamic) size in first place if you have word-wrapping labels to show names/informations or have to show lists of informations?
In Detail:
think about labels with word-wrapping where you don't know how many text you get - because it's Text like a Tweet (yould be one word, could be 280 characters, could be a quote with picture and variable text. think about a label that shows a name - could be "Boris" and could be "Jan-Patrick von Leutheuser Schnarrenberger" that might break to two lines
Think about layouts where you put some "Sub-List"-Information in a cell like: Header is the name of an Order like "Building Garden for Family Johansson" Then the Sub-Info is a list of Workers and Machines planned for a day on that construction place - could be 2 or could be 10 entries.
And then, maybe additionally, you like to first show the title and a line like "4 workers, 6 machines" and when the user taps on that line you like to show the detail ... it doesn't matter then if you try to resize the existing cell or make a "sub"-cell visible because that one would be dynamic sized too
I choosed to go back to ListView (where it works). I didn't have another chance. There was a Listview control from Syncfusion but i don't remember which problems i had with that one. So i'm "back to the roots"
As a side note: I had problems using the Collection View horizontally (as Carousel) too for a lot of reasons. For that i built my own control (basically a Grid working with 3 Views - previous, current, next - where i put my content on).
I still think, Xamarin is a good thing! Having an iOS and Android build on the same Core Code is fantastic! But at the same time it's massive frustrating to have such a bag full of faults, errors, behaviours of controls ...
First you think "hey, this new control is EXACTLY what i could use to save time AND have a great user experience" ... then after a while there are bumps here and there... then you search the web because you think you are doing something wrong ... then you realize that these problems exists since - ages. You see workarounds, usually via custom renderer you try out a log ... until you throw it all away and either redesign your app or building your own custom control from scratch ;)
Hi, I just had a look at this.......This is not a Xamarin issue, it is the issue of not understanding how Collection Views Work.
Collection view repeats the item after a while based on the data template.
You must not change the size or color of the data template element directly as this will effect all elements.
If you intend to do something like changing color or size, bind the size and color to a view model of the item.
I can confirm that this issue can be closed. It works fine.
Updated Sample on how to implement this => CollectionViewCellResize UPDATED.zip
This is wrong. First of all, whenever I encountered this issue, the properties definitely were bound correctly via viewmodel. Second of all, this is clearly a Xamarin issue with view recycling. Say you have a label trigger in your data template that applies a strikethrough decoration if a certain property is set to true, and removes the decoration if that property is set to false: when the collectionview appears for the first time, the strikethrough will only be applied to the items with the property set to "true"... Scroll up and down a little bit, and all of a sudden the strikethrough is applied randomly to a bunch of other cells that have the same property set to "false". There is absolutely no way this is the user's fault. It also definitely wouldn't happen on native recycling-based components like RecyclerView on Android and TableView on iOS.
One of my co-workers suggested working around this issue by only using visibility to control this sort of change inside the cell and it works (obviously not for resizing)... I see this as further proof that this is a recycling issue. Visibility settings are probably taken into account correctly when cells get recycled, but a bunch of other visual properties are not.
This issue can NOT be closed. It is an actual issue that needs fixing.
Hi just want to say my view too, this issue cannot be closed, but the bigger problem is that last release was february and now is nearly July, I think we will be lucky if we get another release at all , and also is this issue in the ipotetical list of things to be fixed in the release. Sorry for being so cynical but they are busy with MAUI and we are left stranded to come up with hacky solutions.
The team I think is too small to cope with all these issues... and even if you did a PR will it be ever merged.... look at the number of PRs that have been there sitting...
Hi, I just had a look at this.......This is not a Xamarin issue, it is the issue of not understanding how Collection Views Work. Collection view repeats the item after a while based on the data template. You must not change the size or color of the data template element directly as this will effect all elements. If you intend to do something like changing color or size, bind the size and color to a view model of the item. I can confirm that this issue can be closed. It works fine. Updated Sample on how to implement this => CollectionViewCellResize UPDATED.zip
This is wrong. First of all, whenever I encountered this issue, the properties definitely were bound correctly via viewmodel. Second of all, this is clearly a Xamarin issue with view recycling. Say you have a label trigger in your data template that applies a strikethrough decoration if a certain property is set to true, and removes the decoration if that property is set to false: when the collectionview appears for the first time, the strikethrough will only be applied to the items with the property set to "true"... Scroll up and down a little bit, and all of a sudden the strikethrough is applied randomly to a bunch of other cells that have the same property set to "false". There is absolutely no way this is the user's fault. It also definitely wouldn't happen on native recycling-based components like RecyclerView on Android and TableView on iOS.
One of my co-workers suggested working around this issue by only using visibility to control this sort of change inside the cell and it works (obviously not for resizing)... I see this as further proof that this is a recycling issue. Visibility settings are probably taken into account correctly when cells get recycled, but a bunch of other visual properties are not.
This issue can NOT be closed. It is an actual issue that needs fixing.
Sorry, I was just answering in the context of the original poster where he changed the Data Template directly in the Xaml.cs file. This is wrong and will effect all the recycled views.
The fix can be seen in my sample where I binded height and color to the view model, this works fine even via data triggers but the key is to bind everything. Bindings have no apparent performance hit since they introduced compiled bindings. I have a complex collection view which resizes and changes colors correctly.
Here is example of my collection view which is dynamicly changing colors, icons and etc. It works fine and scrolls buttery smooth too.
@azrinsani - dude, no! it cannot be closed :/
If you have a layout where you simple don't know the final size, the rows/cells should be able to resize themselfs.
In Short: I binding the size is your solution - maybe you have a great solution how to get the (dynamic) size in first place if you have word-wrapping labels to show names/informations or have to show lists of informations?
In Detail:
think about labels with word-wrapping where you don't know how many text you get - because it's Text like a Tweet (yould be one word, could be 280 characters, could be a quote with picture and variable text. think about a label that shows a name - could be "Boris" and could be "Jan-Patrick von Leutheuser Schnarrenberger" that might break to two lines
Think about layouts where you put some "Sub-List"-Information in a cell like: Header is the name of an Order like "Building Garden for Family Johansson" Then the Sub-Info is a list of Workers and Machines planned for a day on that construction place - could be 2 or could be 10 entries.
And then, maybe additionally, you like to first show the title and a line like "4 workers, 6 machines" and when the user taps on that line you like to show the detail ... it doesn't matter then if you try to resize the existing cell or make a "sub"-cell visible because that one would be dynamic sized too
I choosed to go back to ListView (where it works). I didn't have another chance. There was a Listview control from Syncfusion but i don't remember which problems i had with that one. So i'm "back to the roots"
As a side note: I had problems using the Collection View horizontally (as Carousel) too for a lot of reasons. For that i built my own control (basically a Grid working with 3 Views - previous, current, next - where i put my content on).
I still think, Xamarin is a good thing! Having an iOS and Android build on the same Core Code is fantastic! But at the same time it's massive frustrating to have such a bag full of faults, errors, behaviours of controls ...
First you think "hey, this new control is EXACTLY what i could use to save time AND have a great user experience" ... then after a while there are bumps here and there... then you search the web because you think you are doing something wrong ... then you realize that these problems exists since - ages. You see workarounds, usually via custom renderer you try out a log ... until you throw it all away and either redesign your app or building your own custom control from scratch ;)
Noted. I have a very complex layout too (see picture above). For dynamic heights, have you tried using grids in the collection view data template? Row definitions must be set to auto. Finally, (i'm sure you've done this) set the Collection view's ItemSizingStrategy="MeasureAllItems"
Sorry, I was just answering in the context of the original poster where he changed the Data Template directly in the Xaml.cs file. This is wrong and will effect all the recycled views.
The OP may be wrong, but the devs here marked actual recycling related issues as duplicates of this one, which is why people don't want it closed.
@azrinsani My intent in creating this issue was to highlight that the specific example given in the Xamarin Documentation here produces an unexpected side effect contrary to what the documentation would indicate:
The documentation states:
Items in a CollectionView can be dynamically resized at runtime by changing layout related properties of elements within the DataTemplate.
and then goes on to show a sample where an individual items' height is changed dynamically, which I replicated in my attached project. This would suggest to the reader that only the individual touched cell's item size would be changed, and no others in the list.
(That there is also a related property ItemSizingStrategy
which by default is set to MeasureAllItems
would also suggest that even recycled cells should be re-measured so they would always display correctly)
Either the documentation should be amended to reflect that changes to Data Template element properties can lead to undesired behaviour when cells are recycled or the documentation is assumed to be correct and the CollectionView is not behaving as expected, hence me raising the issue quite some time ago now, to get clarity.
This issue has been quite long lived, commented on and linked to from other issues - I'd be quite happy to see it closed so long as there is a solution that satisfies everyone who has an interest in it / has commented/linked to it.
sure i've tried it with a Grid inside the template.
This is a Bug or a Problem. It doesn't work. Since then i'm back to ListView (where it works) - but there i have problems using SlideView for my own context- or info-elements to show when you slide a row to a side. The only thing that works here is a good old contextItem which is very fixed layout on iOS and top-screen-contextmenu on android ... i don't like it but hey, i cannot use CollectionView because of this problem (and a few others i cannot recall ... too long ago)
@azrinsani I created a repo (https://github.com/Eltee-Taiwo/s-Xamarin-Forms-Collection-View-Duplicate) to illustrate the basics of what's happening. No dynamic resizing or anything complicated. It's just a collection view with 7 items but after the 6th item I'm seeing the first item again....
The collection view on android simply cannot handle more than 6 items gracefully and starts to repeat!
Edit: If I recall correctly it's even worse on iOS but I'm not on my laptop right not to post screenshots of that.
Hello fellow Xamarin sufferers:
I hope this helps someone but after hours of digging I finally found a solution! In my case, I am using a custom control for my data template and I found out that the problem is in OnBindingContextChanged()
.
After the 6th item, the constructor for my control wasn't being called anymore and just the binding context was being updated. So I found that by updating the properties of my controls in OnBindingContextChanged()
the collection view data template updated correctly. Here's a PR showing me updating the properties based on my sample repo above: https://github.com/Eltee-Taiwo/s-Xamarin-Forms-Collection-View-Duplicate/pull/1/files
Hopefully this helps someone. We're in this together ✊
gging I finally found a solution! In my case, I am using a custom control for my data template and I found out that the problem is in
OnBindingContextChanged()
.After the 6th item, the constructor for my control wasn't being called anymore and just the binding context was being updated. So I found that by updating the properties of my controls in
OnBindingContextChanged()
the collection view data template updated correctly. Here's a PR showing me updating the
Collectionviews will only generate enough UI Elements based on the data template that can cover about 2.5 times the screen. In your case, 6 is the number. As the user scroll down (or right) the earlier elements will be recycled. Even though you may have 10000 elements, in reality Xamarin only create 6 elements. That's sort of how it works.
gging I finally found a solution! In my case, I am using a custom control for my data template and I found out that the problem is in
OnBindingContextChanged()
. After the 6th item, the constructor for my control wasn't being called anymore and just the binding context was being updated. So I found that by updating the properties of my controls inOnBindingContextChanged()
the collection view data template updated correctly. Here's a PR showing me updating theCollectionviews will only generate enough UI Elements based on the data template that can cover about 2.5 times the screen. In your case, 6 is the number. As the user scroll down (or right) the earlier elements will be recycled. Even though you may have 10000 elements, in reality Xamarin only create 6 elements. That's sort of how it works.
Exactly. Which in my opinion is what is causing everyone's problems. And that is becuase Xamarin is only creating 2.5x elements. As such a lot of properties are getting carried over from old elements and have to be manually reassigned in OnBindingContextChanged
No, it's not "what causing everyone's problems" ;) It's a good thing, that this control is reusing elements - that's how it's designed and how it should be to be snappy and using less resources. Good!
The (one...) problem is, that the controls itself are not fully aware of this.
I saw other problems with such caching / reusing strategy when i tried to use the SwipeView with a ListView and custom ViewCells... it works for the first controls - but after scrolling further or rebuilding the data (because of filtering the ObservableCollection for a search) it stops working properly .. but that's a different story :)
In conclusion i have to say: After all this time now and some replies i can see, i'm not convinced that this problem will be fixed any time soon... i'm not even convinced that this one is seen as a problem. Of course there are lots of mistakes one can make using any control... and i think we will read more of them in this thread in the future - and none of them will fix the underlaying problem.
I had to meet timelines and i gave up on this control long time ago.
A lot more work, not as fancy as a good control - but after all it works and i can debug and fix it myself
No, it's not "what causing everyone's problems" ;)
Bummer. I was just saying what worked for me, took a guess, and hoped it would help someone else. Good luck!
Bummer. I was just saying what worked for me, took a guess, and hoped it would help someone else. Good luck!
I didn't mean to be offensive - please pardon me for being a bit over-emotional because of my frustration with such bugs/problems for such a long time.
See, if there is a specific problem and someone came in with a similar problem which is caused by using it not properly and then saying "the causes everyone's problems" ... my nerves are a bit thin on that side after over a year ...
So I hope you pardon me: Yes, what you find out is a solution to everyone who made the same mistake in using the control. Absolutely and this mistake is easy to make without realizing it - so thank you
But it's not a solution to the initial problem :)
Hi any workaround to this issue please I am also dynamically changes sizes of row from a custom control which is then defines in datatemplate
Any update?
I think you could say that XF is almost dead. The Team is working on MAUI and maybe everything is going fine with it, we will see.
Workaround? I rolled back to the ListView on most pages/view There is a Bug with the iOS-Version when you resize rows at runtime but you can go around it with a Custom View Renderer for the CellView like this:
In XForms make a class for your ViewCells: `public class AutoViewCell : ViewCell { public Action<object, int> ReloadRow; public void DFUpdateSize() { //-- Der Workaround ist erstmal für iOS relevant if (Device.RuntimePlatform == Device.iOS) { if (this.Parent is ListView listView) { if (listView.ItemsSource == null) return;
int idx = -1;
var items = listView.ItemsSource.GetEnumerator();
items.Reset();
while (items.MoveNext())
{
idx++;
if (items.Current == this.BindingContext)
{
break;
}
}
this.ReloadRow?.Invoke(this, idx);
}
}
else
{
this.ForceUpdateSize();
}
}
}`
In the iOS-Project make a custom renderer for it like: ` [assembly: ExportRenderer(typeof(AutoViewCell), typeof(AutoViewCellRenderer))] namespace DATAflor.Project.iOS { public sealed class AutoViewCellRenderer : ViewCellRenderer { private UITableView _tableView;
public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv)
{
var autoViewCell = (AutoViewCell)item;
var cell = base.GetCell(item, reusableCell, tv);
_tableView = tv;
if (cell != null)
{
autoViewCell.ReloadRow = AutoViewCell_ReloadRow;
}
return cell;
}
private void AutoViewCell_ReloadRow(object sender, int e)
{
var idxp = NSIndexPath.FromItemSection(e, 0);
if (idxp == null)
return;
var cellIndexPath = new NSIndexPath[] { idxp };
_tableView?.ReloadRows(cellIndexPath, UITableViewRowAnimation.Automatic);
}
}
}`
And use your own .ReloadRow()' from now on.
In some cases i switched to a bindable layout to fill a view with my own "row"-Views via binding -- and in some cases i simply put a scrollview on a page and filled it in a loop when i need it (only suitable when you have only a few rows, like for a Data-Detail-View, some kind of menu or setting view etc.)
For my private projects i think i will install Flutter and go thru the tutorials to see how this is working ...
Description
When changing the size (and background colour) of a CollectionView item at runtime (as detailed here in the Xamarin Docs) subsequent off screen items several rows down are also resized as you scroll down the list.
This is happening on both Android and iOS, with iOS also producing odd item display behaviour as the list is updated after the resize which then corrects upon first touch when scrolling.
Steps to Reproduce
Expected Behavior
Only individual CollectionView items that have been dynamically resized should change their appearance.
Actual Behavior
Presumably due to cacheing / recycling other CollectionView items that are off screen and scrolled into view are having their appearance (size and background colour) changed.
Basic Information
Versions with issue:
Last known good version: Unknown
IDE: Visual Studio Community 2019 for Mac (Version 8.4.3 (build 12))
Platform Target Frameworks:
Affected Devices:
Screenshots
Initial view of 24 Cyan items, first item tapped to resize, scroll down and another resized item also shown :
iOS post resize also sizes the remaining visible items oddly until the first touch :![IMG_56A5599F6504-1](https://user-images.githubusercontent.com/11272635/74238968-ccbaf580-4cce-11ea-97f8-42baf2aa8e5e.jpeg)
Reproduction Link
CollectionViewCellResize.zip
Workaround
In my case I reverted to using a derived ListView ensuring
ListViewCachingStrategy
is not set toRecycleElement
and in an iOS ListView renderer callUITableView.BeginUpdates and UITableView.EndUpdates
to refresh the list after an item resize. Android works without needing a forced refresh of the native control.