Open toomasz opened 5 years ago
Duplicate of #5763
@samhouts I see its similar to other issue but:
The CollectionView is meant to expand to its available vertical space.
Why is that? I think it should have option not to expand to all available vertical space, like most controls. It's very common use case, lets say I want to have two lists, one below other and some buttons between them. Without this option it's impossible. Or is there some way?
@samhouts #5763 is a FlexLayout issue.
Also, the current layout behavior of CollectionView is basically the same as what ListView does (always maximally expanding, no matter what the layout options are); we may want to reconsider this for CollectionView. I'd like to reopen this one, at least for now.
(I'm not saying we will change it - just that I'd like to think about it some more.)
I saw this bug report is closed and hence I created a new one few hours ago with my real use case explaining the same issue
Is there any workaround to tame a CollectionView's vertical extent?
@Tragetaschen I haven't found one but maybe I'm missing something. @hartez could you advice on how to stop collection view expanding vertically? Is it possible currently?
I have the CollectionView in a ScrollView+StackLayout.
When the item template has fixed size (i.e. you can use ItemSizingStrategy="MeasureFirstItem"
), I have successfully bound HeightRequest
to the same object as the ItemsSource
with an IValueConverter that basically does
n * itemTemplateHeight
+ (n-1) * itemSpacing
+ ε // 1, 2 or something else to accomodate for internal rounding errors
I able to control the height of CollectionView using AbsoluteLayout.
CollectionView should only take up the space needed to display the items, if we want to take up the entire screen we would specify this as we do with everything else.
having a collection view that only takes the necessary space is a must for me. I would like to replace some hacky flexlayouts with collectionviews, but the spurious space it adds to the layout makes it useless.
Please at least add an option for the user to control the layout. There are plenty of users out there who need this feature! At least there is a chance to correct this in the new collectionview control!
If nothing CollectionView
-specific features are used, you can get around this by binding to BindableLayout
on StackLayout
.
This seems like something that should exist with collection view seeing as you can create a horizontal collection and set the ItemSizingStrategy="MeasureAllItems". I would think the vertical height of the collection view would only be as high as each item. So if a collection view which scrolls horizontally exists at the bottom of a page, it is only taking up the space of the items in view, but instead it just takes over the whole page.
So basically the only easy way is to hardcode HeightRequest in CollectionView element?
I'm doing similar to what @Tragetaschen suggested. Works fine. However not very elegant and would be ideal if VerticalOptions="Start" would work as expected.
Any work around? why is this still bugged?
I would also like to see CollectionView respect the verticalOptions="start". In my case it is a horizontal CollectionView in a stacklayout in a scrollview and the stacklayout seems to take the height of the screen, even though there is only a limited height needed.
A workaround would also be appreciated while awaiting a fix.
The following CollectionView is in an Auto row and displays a narrow horizontally scrolling collection of strings. The required height is minimal. The height of the CollectionView fills the screen on my Nexus 5 phone. If that's expected behaviour so be it, but it doesn't make much sense to me.
<CollectionView Grid.Row="3" ItemsSource="{Binding Categories}" ItemsLayout="HorizontalList" VerticalOptions="Start">
<CollectionView.ItemTemplate>
<DataTemplate>
<Label Text="{Binding Text}"/>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
Xamarin rocks! Here seems as good a place as any to say thank you and keep up the good work! :)
I too am really looking forward to a change on how this works. Why would a horizontal list take up full height of a page? Also if used for showing just a few items vertically, you can't show anything below it, without the user having to scroll almost a full empty page.
Basically, CollectionView is currently designed with the assumption that it will be the only view on a page. That just doesn't hold true for real-life apps.
Until then, I guess the "workaround" is to use StackLayout
with BindableLayout
instead of CollectionView
. That just has terrible performance on longer lists, so it's not a great solution either.
Until then, I guess the "workaround" is to use
StackLayout
withBindableLayout
instead ofCollectionView
. That just has terrible performance on longer lists, so it's not a great solution either.
Inrego, one way to work around it is to wrap a StackLayout (for example) around the Collectionview and bind the HeightRequest of the StackLayout to a property in the viewmodel that calculates the required height based on some things (contents of the CollectionView items).
Not ideal but it worked in my case.
Until then, I guess the "workaround" is to use
StackLayout
withBindableLayout
instead ofCollectionView
. That just has terrible performance on longer lists, so it's not a great solution either.Inrego, one way to work around it is to wrap a StackLayout (for example) around the Collectionview and bind the HeightRequest of the StackLayout to a property in the viewmodel that calculates the required height based on some things (contents of the CollectionView items).
Not ideal but it worked in my case.
I'm just speculating, but calculating the height of each item would also yield not so good performance on large lists. Of course, this is only a problem when the list is smaller than the page, so I could do the calculation only if there's not enough items to fill the page.
But then again, looks like it might be solved soon. And it'll be a while before my app hits production. So I can live with the bad performance of StackLayout until then I think.
But still good to have the options here for others to see.
@pspeybro How would you go about calculating the height of the displayed items? If I have set a fixed height on the template then maybe I can use that, but what if it is not? Is there a way to access the displayed views so I can write a behavior (maybe?) that can adjust the height when the ItemSource changes?
@pspeybro How would you go about calculating the height of the displayed items? If I have set a fixed height on the template then maybe I can use that, but what if it is not? Is there a way to access the displayed views so I can write a behavior (maybe?) that can adjust the height when the ItemSource changes?
@AmrAlSayed0 , in my case, I was adding extra rows (users) in vertical stacklayout that was inside de collectionview DataTemplate (while collectionview has horizontal orientation). A user can click something to add an extra user. In my viewmodel, when an extra row is added, I also trigger the OnPropertyChanged of a Height property that calculates the required height, based on the number of users. This Height property is bound to the HeightRequest of a Stacklayout that contains the horizontal collectionview.
Not very pretty, but it works for me...
Any news on this. Starting using the collectionview and hit upon this almonst straight away. Then found this more than year old bug issue. It really doesn't make much sense from a layout POV to expand like this
This is a +1,000 for me. It seems insane that the collection view is so single use. I can't do something so simple as have a label under my list be cause the list (even if it only has a fe items in it) is huge! It makes the collection view nearly worthless. This needs to be fixed!
Every component containing HorizontalOptions and VerticalOption should expand and fill according to value set. It doesn't make sense that a component is overriding these values. I would really like to see that the properties remains for CollectionView and the components size can be adjusted by the size of the collection.
This feature is very important and it should be given high priority
Any news on this?
Just tried to do a very simple horizontal collections view to display some tags, and the entire thing expands vertically to the whole screen eventhough I set VerticalOptions="Center" and the elements inside the collection view is not above 10 units high and I set the ItemsLayout to "HorizontalList".
Why?
May be the logic behind this behaviour is that listviews expand horizontally and they thought the same would apply to horizontal lists(expanding vertically)...?
I had to set the height of the entire collection using the "HeigthRequest" property, for my use case this will sufice, but what If I had itens with dinamic height?
PS:I would like to take this oportunity to say that Xamarin Forms is awesome!!!
Sorry but, why make the assumption that ANY control view should be taking up the entire screen space as "expected behaviour"??? Isn't this why we have Vertical/Horizontal Options properties on our views, so we can specify we WANT this behaviour?
This isn't only true of the CollectionView, but ListView as well!
@samhouts is there any movement on this bug being fixed soon? I would really like to use CollectionView for performance over StackLayout as it's having an impact on my users experience.
Use grid and set the row height to "*", put the CollectionView to that row and set its HeightRequest to 0. The CollectionView will consume the size of the grid's row.
Use grid and set the row height to "*", put the CollectionView to that row and set its HeightRequest to 0. The CollectionView will consume the size of the grid's row.
Unfortunately, it didn't work for me.
@Rothanan Are you sure you implemented it correctly? It seems quite impossible for a view to expand past the bounds of its parent. Or did the CollectionView stretch the height of the Grid?
@Rothanan Sorry for the very late reply, I set the HeightRequest = 0 at the .cs of the view where the CollectionView was declared. Try to rerun the app, sometimes the code does not reflect immediately, idk why..
Same here
Instead of
<CollectionView ItemsSource="{Binding Categories}">
<CollectionView.ItemTemplate>
<DataTemplate>
<Label Text="{Binding Text}"/>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
..write..
<StackLayout BindableLayout.ItemsSource="{Binding Categories}" >
<BindableLayout.ItemTemplate>
<DataTemplate>
<Label Text="{Binding Text}"/>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
.. and Bob's your uncle!
Instead of
<CollectionView ItemsSource="{Binding Categories}"> <CollectionView.ItemTemplate> <DataTemplate> <Label Text="{Binding Text}"/> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView>
..write..
<StackLayout BindableLayout.ItemsSource="{Binding Categories}" > <BindableLayout.ItemTemplate> <DataTemplate> <Label Text="{Binding Text}"/> </DataTemplate> </BindableLayout.ItemTemplate> </StackLayout>
.. and Bob's your uncle!
Yeah.. if you don't want any of the benefits of CollectionView like smooth scrolling and reused elements or any of the other features of CollectionView. Then sure, by all means - use something else than CollectionView.
As an alternative to what @nykkel mentions, we can cover the CollectionView in a StackLayout instead of a FlexLayout. The CollectionView will push the next element to the end of the layout.
Before
<FlexLayout
BackgroundColor="Blue"
Direction="Column">
<RefreshView>
<CollectionView
BackgroundColor="Yellow">
<CollectionView.ItemTemplate>
<DataTemplate>
...
</DataTemplate>
</CollectionView.ItemTemplate>
<CollectionView.EmptyView>
...
</CollectionView.EmptyView>
</CollectionView>
</RefreshView>
<StackLayout BackgroundColor="Beige">
...
</StackLayout>
</FlexLayout>
After
<StackLayout Spacing="0" BackgroundColor="Blue">
<RefreshView>
<CollectionView
BackgroundColor="Yellow" >
<CollectionView.ItemTemplate>
<DataTemplate>
...
</DataTemplate>
</CollectionView.ItemTemplate>
<CollectionView.EmptyView>
...
</CollectionView.EmptyView>
</CollectionView>
</RefreshView>
<StackLayout BackgroundColor="Beige">
...
</StackLayout>
</StackLayout>
So who is gonna do it ? Who is gonna fix it, or is this expected behavior ?
In case of a horizontal collectionView, wrapping the collectionview to a stackLayout would solve the problem in my opinion. Something like this:
<StackLayout>
<CollectionView ItemsSource="{Binding TabItems, Mode=OneWay}">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical"
Span="3"/>
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<!--Content-->
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
Let me know what you think or if you have better workarounds.
+1 For fix please. This issue is frustrating. I'm trying to have achieve several lists in a single page, either with the whole page being scrollable or each list view being scrollable. I couldn't figure out why the listview was behaving differently to other components.
This is still an issue with .NET MAUI as well when CollectionView is inside RefreshView.
Description
CollectionView, when places with other controls in for example stackLayout, takes too much space vertically. It should only take as much space as total items height(at least when VerticalOptions="Start" are set)
Steps to Reproduce
Expected Behavior
CollectionView should only take as much space as sum of it's items
Actual Behavior
CollectionView expads to higher height or takes all space available
Basic Information
Screenshots
UWP:
Android:
Reproduction Link
CollectionViewRepro.zip