Xamarin.Forms.CollectionView Spec

Created on 27 Jun 2018  ·  178Comments  ·  Source: xamarin/Xamarin.Forms

CollectionView

The current Forms ListView design and implementations are very complex and challenging to maintain, while often not providing the flexibility that users would like. Because of the complexity of the implementations and the backward compatibility requirements, ListView bugs can be difficult to find and fix.

The goal of the CollectionView effort is to address these problems by simplifying the API and embracing the capabilities of the native platforms' list-building controls. To that end:

  • CollectionView removes the concept of Cells entirely. While convenient in some cases, the Cell concept introduces a great deal of complexity into the native implementations of ListView. Everything that is possible with Cells can be accomplished with reusable DataTemplates.

  • CollectionView reduces the API surface. Several properties and events from ListView are not available in CollectionView. Several of these are easily replaceable within DataTemplates; others were very specific to particular platforms and never really belonged in the first place. A list of these changes can be found below.

  • CollectionView aims to be more flexible by not baking in assumptions about layout. This allows us to support layouts which users have long been asking for (e.g., a HorizontalListView) and which the native implementations already provide.

_Note: Nothing in this document should be taken as an indication that the current ListView will be removed or will cease to be maintained. This effort is simply aiming to provide an alternative control which will more easily serve the needs of many Forms users._

_Note: Nothing in this specification is guaranteed to be final; all features, implementations, and interfaces are subject to change._

Current completion status of the features specified below

Supporting APIs

In order to provide users with a more modern list, the CollectionView effort will include a some supporting APIs:

  • FontIconSource - using scalable glyphs as icons; the intent is to support glyphs whereever Forms currently supports images. This is obviously a desirable feature in many parts of Forms, but it's also absolutely essential to support contextual swipe gestures in CollectionView (see the FontIconSource spec).

  • SwipeView - Provides support for swiping on an element to execute or reveal further actions (see the SwipeView spec).

Layout Specification

This spec provides for the developer to specify whether items to be laid out in a vertical list, horizontal list, or a grid. The underlying native classes all support these layout types. (Note that on iOS, this spec assumes the use of UICollectionView rather than UITableView.)

The specifications given to the CollectionView are mapped to native layouts in each renderer. For example, if a grid layout is specified, on iOS the renderer will (by default) use a UICollectionViewFlowLayout. On Android, the default will be GridLayoutManager; on UWP, GridView.

Forms does not participate in the layout of the items in the repeater (beyond generating the items Views themselves); this portion of the layout is entirely native.

The selection of layout methods to use in each renderer will be user-modifiable; if a user would rather use StaggeredGridLayoutManager on Android, this could be achieved by modifying the selection method and returning the desired layout manager.

ListView API Removals

  • IsPullToRefreshEnabled - this is now handled by the RefreshView.
  • IsRefreshing - this is now handled by the RefreshView.
  • RefreshCommand - this is now handled by the RefreshView.
  • HasUnevenRows - this is now ItemSizingStrategy.
  • RowHeight - this is now determined by the first item to be laid out.
  • SeparatorVisibility - CollectionView does not include built-in separators; users can provide these (if desired) in their templates.
  • SeparatorColor - CollectionView does not include built-in separators; users can provide these (if desired) in their templates.
  • GroupShortName - this property existed to support jump lists and semantic zoom; CollectionView phase 1 does not support these features.

API

ContextItem

ContextItem provides a way to specify a contextual interaction, often displayed as part of a context menu.

public class ContextItem
{
    public static readonly BindableProperty TextProperty;
    public string Text { get; set; }

    public static readonly BindableProperty CommandProperty;
    public ICommand Command { get; set; }

    public static readonly BindableProperty CommandParameterProperty;
    public object CommandParameter { get; set; }

    public static readonly BindableProperty IsEnabledProperty;
    public bool IsEnabled { get; set; }

    public static readonly BindableProperty IconProperty;
    public ImageSource Icon { get; set; }

    public event EventHandler Invoked;
}

Properties

| API | Description |
| ------------- | ------------- |
| Text | Gets or sets the text description displayed on the item. |
| Command | Gets or sets the command to execute when this item is invoked. |
| CommandParameter | |
| IsEnabled | Gets or sets a value indicating whether the user can interact with the context item. |
| Icon | Gets or sets the graphic content of the item. |

Events

| API | Description |
| ------------- | ------------- |
| Invoked | Occurs when user interaction indicates that the command represented by this item should execute. |

ContextMenu

Provides a way to specify a set of interactions to be displayed in a context menu. A ContextMenu can be provided for any VisualElement, and is activated/displayed according to the native platform conventions.

public static class ContextMenu
{
    public static readonly BindableProperty MenuItemsProperty =
            BindableProperty.CreateAttached("MenuItems", typeof(ContextMenuItems), typeof(VisualElement));
}


public class ContextMenuItems : IList<ContextItem>
{
}

RefreshView

Moved to #5882

SelectionMode

Provides the selection mode behaviors for a CollectionView.

public enum SelectionMode 
{
    None,
    Single,
    Multiple
}

SelectionChangedEventArgs

public class SelectionChangedEventArgs : EventArgs
{
    public IReadOnlyList<object> PreviousSelection { get; }
    public IReadOnlyList<object> CurrentSelection { get; }
}

Properties

| API | Description |
| ------------- | ------------- |
| PreviousSelection | Gets the list of items that were selected before the selection changed. |
| CurrentSelection | Gets the list of items that are selected after the selection change. |

IItemsLayout

Marker interface to indicate that the implementing class specifies a layout used by CollectionView to arrange its items.

public interface IItemsLayout {}

ItemsLayoutOrientation

Enumerates the possible orientations for an ItemsLayout. As items are added, the CollectionView expands in the orientation direction.

public enum ItemsLayoutOrientation
{
    Vertical,
    Horizontal
}

ItemsLayout

Base class for Forms-provided items layouts.

public abstract class ItemsLayout : IItemsLayout
{
    public ItemsLayoutOrientation Orientation { get; }

    protected ItemsLayout(ItemsLayoutOrientation orientation);

    public static readonly BindableProperty SnapPointsAlignmentProperty;
    public SnapPointsAlignment SnapPointsAlignment { get; set; }

    public static readonly BindableProperty SnapPointsTypeProperty;
    public SnapPointsType SnapPointsType { get; set; }  

    public static readonly BindableProperty ItemSpacingProperty;
    public Thickness ItemSpacing {get; set;}
}

Properties

| API | Description |
| ------------- | ------------- |
| ItemsLayoutOrientation | Specifies the direction in the which the CollectionView expands as items are added. |
| SnapPointsType | Specifies the behavior of snap points when scrolling the view. |
| SnapPointsAlignment | Specifies how snap points are aligned with items in the view. |
| ItemSpacing | Specifies the empty space around each item. |

ListItemsLayout

public class ListItemsLayout : ItemsLayout
{
    public ListItemsLayout(ItemsLayoutOrientation orientation) : base (orientation);

    public static readonly IItemsLayout VerticalList = new ListItemsLayout(ItemsLayoutOrientation.Vertical); 
    public static readonly IItemsLayout HorizontalList = new ListItemsLayout(ItemsLayoutOrientation.Horizontal); 
}

Static Members

| API | Description |
| ------------- | ------------- |
| VerticalList | Specifies a single column list in which the list grows vertically as new items are added. |
| HorizontalList | Specifies a single row list in which the list grows horizontally as new items are added. |

GridItemsLayout

Defines a multi-row or multi-column layout.

public class GridItemsLayout : ItemsLayout
{
    public static readonly BindableProperty SpanProperty;
    public int Span { get; set; }

    public GridItemsLayout([Parameter("Span")] int span, [Parameter("Orientation")] ItemsLayoutOrientation orientation) : base (orientation);
}

SnapPointsAlignment

Enumerates the possible alignments for snap points in a ListItemsLayout.

public enum SnapPointsAlignment
{
    Start,
    Center,
    End
}

Enum Values

| API | Description |
| ------------- | ------------- |
| Start | Snap points are aligned with the leading edge of items. |
| Center | Snap points are aligned with the center of items. |
| End | Snap points are aligned with the trailing edge of items. |

SnapPointsType

Enumerates the possible behaviors for snap points in a ListItemsLayout.

public enum SnapPointsType
{
    None,
    Optional,
    Mandatory,
    OptionalSingle,
    MandatorySingle,
}

Enum Values

| API | Description |
| ------------- | ------------- |
| None | Scrolling does not snap to items. |
| Optional | Content snaps to the closest snap point to where scrolling would naturally stop along the direction of inertia, if any snap points are sufficiently close. |
| Mandatory | Content always snaps to the closest snap point to where scrolling would naturally stop along the direction of inertia. |
| OptionalSingle | Same behavior as Optional, but only scrolls one item at a time. |
| MandatorySingle | Same behavor as Mandatory, but only scrolls one item at a time. |

Properties

| API | Description |
| ------------- | ------------- |
| Span | Specifies the number of items to lay out in the constrained direction. |

ItemSizingStrategy

Provides the possible item measurement strategies to be used by the CollectionView.

public enum ItemSizingStrategy
{
    MeasureAllItems,    
    MeasureFirstItem
}

Enum Values

| API | Description |
| ------------- | ------------- |
| MeasureAllItems | Each item is measured individually. |
| MeasureFirstItem | Only the first item is measured; all subsequent items are assumed to be the same size as the first. |

ItemsUpdatingScrollMode

Defines constants that specify the scrolling behavior of items while updating.

public enum ItemsUpdatingScrollMode
{
    KeepItemsInView,
    KeepScrollOffset,
    KeepLastItemInView
}

Enum Values

| API | Description |
| ------------- | ------------- |
| KeepItemsInView | Adjusts the scroll offset to keep the first visible item in the viewport when items are added. |
| KeepScrollOffset | Maintains the scroll offset relative to the beginning of the list when items are added. |
| KeepLastItemInView | Adjusts the scroll offset to keep the last visible item in the viewport when items are added. |

CollectionView

Displays a list of items.

public class CollectionView : View
{
    public static readonly BindableProperty ItemsLayoutProperty;
    public IItemsLayout ItemsLayout { get; set; }

    public static readonly BindableProperty ItemsSourceProperty;
    public IEnumerable ItemsSource { get; set; }

    public static readonly BindableProperty ItemTemplateProperty;
    public DataTemplate ItemTemplate { get; set; }

    public static readonly BindableProperty ItemsUpdatingScrollMode;
    publio ItemsUpdatingScrollMode ItemsUpdatingScrollMode { get; set; }

    public static readonly BindableProperty HeaderProperty;
    public object Header { get; set; }

    public static readonly BindableProperty HeaderTemplateProperty;
    public DataTemplate HeaderTemplate { get; set; }

    public static readonly BindableProperty IsHeaderStickyProperty;
    public bool IsHeaderSticky { get; set; }

    public static readonly BindableProperty FooterProperty;
    public object Footer { get; set; }

    public static readonly BindableProperty FooterTemplateProperty;
    public DataTemplate FooterTemplate { get; set; }

    public static readonly BindableProperty IsFooterStickyProperty;
    public bool IsFooterSticky { get; set; }

    public static readonly BindableProperty EmptyViewProperty;
    public object EmptyView { get; set; }

    public static readonly BindableProperty EmptyViewTemplateProperty;
    public DataTemplate EmptyViewTemplate { get; set; }

    public static readonly BindableProperty GroupDisplayBindingProperty;
    public BindingBase GroupDisplayBinding { get; set; }

    public static readonly BindableProperty GroupHeaderTemplateProperty;
    public DataTemplate GroupHeaderTemplate { get; set; }

    public static readonly BindableProperty GroupFooterTemplateProperty;
    public DataTemplate GroupFooterTemplate { get; set; }

    public static readonly BindableProperty ItemSizingStrategy;
    public bool ItemSizingStrategy { get; set; }

    public static readonly BindableProperty IsGroupingEnabledProperty;
    public bool IsGroupingEnabled { get; set; }

    public static readonly BindableProperty SelectionModeProperty;
    public SelectionMode SelectionMode { get; set; }

    public static readonly BindableProperty SelectedItemProperty;
    public object SelectedItem { get; set; }

    public static readonly BindableProperty SelectedItemsProperty;
    public IList<object> SelectedItems { get; set; }

    public static readonly BindableProperty SelectionChangedCommandProperty;
    public ICommand SelectionChangedCommand;

    public static readonly BindableProperty SelectionChangedCommandParameterProperty;
    public object SelectionChangedCommandParameter;

    public static readonly BindableProperty RemainingItemsThresholdProperty;
    public int RemainingItemsThreshold { get; set; }

    public void ScrollTo(object item, object group = null, 
        ScrollToPosition position = ScrollToPosition.MakeVisible, bool animate = true);

    public void ScrollTo(int index, int groupIndex = -1, 
        ScrollToPosition position = ScrollToPosition.MakeVisible, bool animate = true);

    public event EventHandler<SelectionChangedEventArgs> SelectionChanged;

    public event EventHandler<EventArgs> RemainingItemsThresholdReached; 
}

Properties

| API | Description |
| ------------- | ------------- |
| ItemsLayout | Gets or sets the layout specification for the list. |
| ItemSizingStrategy | User hint which can be provided to the control to improve performance. If this is set to MeasureAllItems (the default), each item will be measured individually. In situations where the item size is intended to be uniform, this value can be set to MeasureFirstItem; only the first item will be measured, and all subsequent items will be given the same size as the first. |
| ItemTemplate | Gets or sets the DataTemplate used to display each item.|
| ItemsUpdatingScrollMode | Gets or sets a value that specifies scrolling behavior when the items are updated. |
| IsGroupingEnabled | Gets or set a value which indicates whether the underlying data should be displayed in groups. |
| Header | Gets or sets the string, binding, or view that will be displayed at the top of the control. |
| HeaderTemplate | Gets or sets a data template to use to format the Header. |
| IsHeaderSticky | Specifies whether the header remains in place as the user scrolls. The default is True |
| Footer | Gets or sets the string, binding, or view that will be displayed at the bottom of the control. |
| FooterTemplate | Gets or sets a data template to use to format the Footer. |
| IsFooterSticky | Specifies whether the footer remains in place as the user scrolls. The default is True |
| EmptyView | Gets or sets the string, binding, or view that will be displayed when the ItemsSource is empty. |
| EmptyViewTemplate | Gets or sets a data template to use to format the EmptyView. |
| GroupHeaderTemplate | Gets or sets a DataTemplate for group headers. |
| GroupFooterTemplate | Gets or sets a DataTemplate for group footers.* |
| ItemsSource | The list of objects to be displayed in the control. |
| SelectionMode | Gets or sets the selection behavior for the control. |
| SelectedItem | Gets or sets the selected item for a SelectionMode of Single. If the selected item is removed from the items source, SelectedItem will be set to null. |
| SelectedItems | Gets or sets the selected items for a SelectionMode of Multiple. If selected items are removed from the items source, they will be removed from SelectedItems and SelectionChanged will be raised. |
| SelectionChangedCommand | Gets or sets the ICommand to execute when the selection changes. |
| SelectionChangedCommandParameter | Gets or sets the parameter for the SelectionChangedCommand. |
| GroupDisplayBinding | Gets or sets the binding to use for displaying the group header. |
| RemainingItemsThreshold | Specifies the threshold of items not yet visible in the CollectionView at which the RemainingItemsThresholdReached event will be raised. The default value is -1, meaning the event will never be raised. A 0, the event will be raised when the final item currently in the ItemsSource is displayed. At values greater than 0, the event will be raised when the ItemsSource currently contains that number of items not yet scrolled to. |

Methods

| API | Description |
| ------------- | ------------- |
| ScrollTo(object item, object group = null, ScrollToPosition position = ScrollToPosition.MakeVisible, bool animate = true) | Scrolls the specified item into view. |
| ScrollTo(int index, int groupIndex = -1, ScrollToPosition position = ScrollToPosition.MakeVisible, bool animate = true) | Scrolls the item at the specified index into view. |

Events

| API | Description |
| ------------- | ------------- |
| SelectionChanged | Raised when the SelectedItem or SelectedItems properties change. This includes changes which occur as a result of changing the SelectionMode property. |
| RemainingItemsThresholdReached | Raised when the CollectionView is scrolled far enough that only RemainingItemsThreshold items have not been displayed. This event can be handled to load more items. |

Scenarios

Chat Application

The developer has an app which has a chat client. Messages appear at the bottom of the list and scroll up off the screen. How can the developer achieve this UI with the proposed API?

In order to achieve this behavior, the developer should set the CollectionView.ItemsUpdatingScrollMode property to KeepLastItemInView. If the user's scroll position is at the end of the CollectionView, the new items will appear at the bottom and will be scrolled into view. If the user's scroll position is elsewhere, the new items will appear at the bottom but the scroll position will remain unchanged.

Snap to closest

The developer's app shows a list of real estate listings. As the user scrolls through the list the scrolling should be smooth until the user stops. When scrolling stops the app's interface should snap the scroll (animated) so that the top most listing is perfectly aligned with the top of the page. The snap should always be in the direction that produces the least amount of motion.

In order to achieve this behavior, the developer should use a ListItemLayout with the following settings:

  • Orienation: Vertical
  • SnapPointsAlignment: Start
  • SnapPointsType: Mandatory

TableView

The developer wishes to recreate a settings page using a TableView like appearance.

The developer will want to use a ListItemsLayout with a Vertical Orientation. The ItemsTemplate should be set to a DataTemplate which recreates the look and feel of a table cell. If the "settings" interface is meant to address more than one type of setting (e.g., if some cells are meant to toggle a setting on/off and others are meant to navigate to a secondary settings screen), then the developer may wish to create a DataTemplateSelector which implements a DataTemplate for on/off settings (with a toggle switch) and a DataTemplate for navigation (with a TapGesture which pushes the secondary settings page onto the navigation stack).

Infinite Scroll

The developer has an app which shows a "news" feed. The "news" feed has an infinite number of potential items so when the user nears the end of the current loaded set of data the app needs to make an asynchronous call to the server to load more data. It is critical to the app that data be loaded before the user would see either blank space or be stopped from scrolling within the limits of network latency/bandwidth. How can the developer achieve this with the proposed API?

To achieve this, the developer should set the RemainingItemsThreshold property and handle the RemainingItemsThresholdReached event. When the event is raised, the handler can make the asynchronous call to the server to load more data into the underlying ItemsSource.

collectionview blocker roadmap enhancement ➕

Most helpful comment

How about Scrolling event to support parallax headers

All 178 comments

How about Scrolling event to support parallax headers

There's a lot to love about this.

FontIconSource

For the FontIconSource though we really do need a way to not use the Unicode value (if we don't want to). If you're looking at a FontIconSource with a value f370 you have no freaking clue what that is supposed to be.

On the other hand, if I can pick and choose what Icon Font's I'm using and give Forms a way to convert fa-app-store-ios to it's unicode equivalent of f370, now I can at a glance know that the icon I'm using is from Font Awesome and it's the iOS App Store icon. By no means am I saying that Forms should have that understanding for every available font baked in (or any for that matter), that can come from either some public gists or be added to the Community Toolkit, etc. Either way we do need a way to use meaningful names.

Lastly I would hope we could get a baked in XAML Extension for this so you might have something like:

<Image Source="{FontIcon fa-app-store-ios,Color={StaticResource primaryColor}}" />

Menus

As I was discussing with @davidortinau earlier, it would be particularly ideal if we can mix and match on the Context Menus to achieve the appropriate results. Some good context on this would be to think of an email client in which you may get one menu when you swipe left and another when you swipe right. Another scenario I would love to see supported would be the cell menu approach like shown in the docs for the iOS CollectionView.

Events

I think it's safe to say I'm biased, but a very large portion of the community is following an MVVM design pattern. Having the SelectionChanged & RemainingItemsThresholdReached events are both important to the API, but it would be fantastic if we could find a way to support these OOB with a ViewModel's version of an event handler... an ICommand.

Since RemainingItemsThresholdReached just sends a plain old EventArgs I think we can safely assume passing null to the command should be fine since we just need to execute the command. For the SelectionChanged, I would tend to think it would be more vital to know the new items, vs the old items so simply passing the new items OOB to a SelectionChangedCommand should be fine. This may not hit every use case, but it at least provides a minimum amount of overhead that a developer needs to add with some EventToCommandBehavior.

Perfect sample that kills current listview is making Calendar control where:
-days (cells) can have many styles :
as promotion day, birthday, disabled / no sale day/ bank holiday ...
embedded icons with different custom fonts in it, cell have shadows if selected, other style when in r
rage, other when at begin and end of range
-selecting date rages is possible
-month header and customized header style
-month headers have buttons that are allowing some special view/actions/display on current month

How about also adding a GroupFooterTemplate?

This is so much needed in Forms :-) CollectionView would eliminate expensive workarounds, solve limitations and probably improve performance in just about every Forms app I made in the past 5 years. Exactly the right approach too - leverage and expose the power of the native platforms.

If there was only ONE enhancement I could request for Forms, this would be it.
(actually, I did that in 2017 in response to @davidortinau)

This is truly awesome and long awaited! The API is clean and straightforward (thanks for renaming HasUnevenRows !).

Scrolling events are very much needed, as suggested by @dhaligas. For parallax animations but also to hide floating action button while scrolling for example.

FontIconSource is a good idea. It might be great to provide a default list of icons, with unicode mapped for every platform (similar to iOS or UWP).

This sounds like exactly what's needed. The API looks much cleaner, having multiple views/containers structured this way should help keep the code cleaner and simpler.

My comments so far:

@dansiegel A command when the Remaining Items Threshold is met would be welcome. Not sure it's needed for SelectedItems though - everything you say (notified of changes, what has changed, and even why) is handled automatically as long as SelectedItems is an ObservableCollection (or anything that implements INotifyCollectionChanged). I'd rather have as little code as possible in CollectionView to keep complexity down.

Scrolling: I completely agree about the scrolling event. We can get it at the moment for Android, but for iOS you have to wrap the UITableViewSource and hijack the Scrolled method.

Most important of all for me would be extensibility. Please don't use internal classes for adapters and TableViewSources, and please in the native renderers expose "CreateAdapter" and "CreateViewSource" methods (and similar for other platforms) where we can create our own type if we want to. We have a custom ListAdapter for drag and drop support on Android, and as mentioned before, a custom UITableViewSources for both scrolling and drag and drop. It's not code I like though because there's wrapping of internal classes etc.

This doesn't just apply to adapters/viewsources. In general in the new API, please add points where we can extend behaviour if we need to.

I think this is a really great and important feature!
iOS is already using the UICollectionView name, that might lead to confusion and incorrect google results when searching for CollectionView. Is this a problem?

Just to get it out of the way, I love basically everything about CollectionView spec. It might be worth splitting some of the things out into separate issues though, since I have thoughts on them, as I'm sure many others do and I can see the conversations getting hard to follow. For example:

This could be added later, but something like:

public class MultipleFontIconsSource : ImageSource
{
    public List<FontIconSource> Icons { get; set; }
}

would be useful, to support stacking icons: https://fontawesome.com/how-to-use/on-the-web/styling/stacking-icons

My feedback:

  1. I'd not put the item selection capabilities in the CollectionView class. Instead, I'd add an abstract base class ListCollectionView derived from CollectionView which has specific capabilities:
public class CollectionView : View
{
   // Common capabilities related to a view capable of displaying a list of items
    public static readonly BindableProperty ItemsLayoutProperty;
    public IItemsLayout ItemsLayout { get; set; }

    public static readonly BindableProperty ItemsSourceProperty;
    public IEnumerable ItemsSource { get; set; }
}

public class ListCollectionView : CollectionView
{
     // Item selection capabilities and other capabilities 

    public static readonly BindableProperty SelectionModeProperty;
    public SelectionMode SelectionMode { get; set; }

    public static readonly BindableProperty SelectedItemProperty;
    public object SelectedItem { get; set; }

    public static readonly BindableProperty SelectedItemsProperty;
    public IList<object> SelectedItems { get; set; }

    public static readonly BindableProperty SelectedItemsProperty;
    public IList<object> SelectedItems { get; set; }
}

My idea is to have a CollectionView similar to the ItemsControl in Windows XAML. The ItemsControl takes a Panel instance which positions the items. In Forms, we'll have CollectionView and IItemsLayout.
By default, if no IItemLayout is given, the default layout could a stack layout. This way we could basically have ItemsSource combined with StackPanel from Windows XAML, or in other words, a bindable StackLayout !

Beside item selection, there are other capabilities which I'd not put in the CollectionView, I'd add these to the ListCollectionView. For example, the CollectionView should not have scrolling. This way it will cover this thread

  1. I'd rename IItemsLayout interface to ICollectionViewLayout. The framework already has Layout and ItemsView. It would be a longer name, but the ICollectionViewLayout is a strong indication what it's for, it's specific to the CollectionView, not some general way of displaying items.

  2. I'd rename ItemsLayout class to OrientedCollectionViewLayout. It's a strong indication what the abstract base class is really for, all the derived classes layout the items in an oriented way. Moreover, using "Oriented" in the name gives the option in the future to add an abstract base class called just "CollectionViewLayout". if some new common functionality is required for all collection view layout classes, not just ones which have orientation.

  3. Removing ViewCell and just use DataTemplate is very welcome, it improves reusability.

  1. Can you share more details about RefreshView?
    I assume RefreshView somehow should map to UIRefreshControl on iOS? How will it work on Android and UWP?

In case anyone is interested, I made some updates to my first comment above.

I agree with @andreinitescu that it would be good to have a way to have a non-scrolling collection. I'm neutral on if that means breaking it into multiple classes or possibly having something like a ScrollMode property. I'll defer to those with a lot more API design experience than myself on that. But it is fairly trivial to implement your own StackLayout based item list with a DataTemplate or template selector, so maybe it's not needed.

While I like the idea of controlling the scroll function, I'm also not coming up with any compelling use cases for a non-scrolling "Collection" that includes all the advanced features of ListView or the proposed CollectionView off the top of my head. My use case for a non scrolling list has always been solved by the trivial item list. My normal reason for not using a ListView is because I don't want selection or I want to horizontally layout the list. Both of those cases appeared to be covered by the proposed spec. I would be interested in any use examples anyone else has for no scroll.

@bmacombe I agree with you that it's "simple" to implement a bindable StackLayout, but that's not the point I think. It's a very common functionality, why not have it in the framework? And with some planning, I think it can be done. Like I already said above, it can be solved by just spreading the functionality in two classes, a base class (similar to ItemsControl in Windows XAML) and CollectionView (ListView). Ideally there should be a Selector class in the hierarchy (see https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.primitives.selector)

I would say the trivial reason to have a non-scrolling option is that some pages need to have a ScrollView for the whole page, and a list of items.

If you do that, right now it is not recommended to put a ListView in a ScrollView. A bindable CollectionView that you could put in there, that still potentially has all the features of a ListView, is something I have had a need for multiple times.

I wrote the same BindableStack thing that everyone else does, but a baked in one would be much nicer to work with.

@adammeaney That makes sense and I've done similar now that I think about it.

@andreinitescu I don't disagree it would be great to have it built in. I think everyone is on the same page for what is needed, just how to best do it. I'm ok with either approach as long as there is a "no scroll" option of some type.

In my own frameworks I always go back and forth in build lots of features into one control or have lots of similar classes with incremental functions. I'll be good with however the Forms team decides to implement it the best, especially considering the underlying platform implementations.

@bmacombe With some planning, I'm hoping we can get two birds with one stone.
For example, an instance of the CollectionView class working in the way I mentioned, if it has no IItemLayout set, it could just be mapped by the renderer mechanism to a native UIStackView on iOS or StackPanel on UWP or LinearLayout on Android. Or, to be easier to implement, it could just use the existing StackLayout to arrange views.

My impression was that a new ListView should aim both fix challenges with existing ListView but also provide a solution to the "RepeatableBinder" thread here

We want to see where ListView2 lands before pushing this spec forward. It contains many of the same needed components and it would be best to avoid duplicating them.

I don't see how putting all the functionality in the CollectionView like the spec here suggests would do the job right.

2680 Could be added to this spec? With regards to ScrollBar enablement.

@andreinitescu

Can you share more details about RefreshView?
I assume RefreshView somehow should map to UIRefreshControl on iOS? How will it work on Android and UWP?

On UWP, we'll likely be using RefreshContainer. On Android, probably SwipeRefreshLayout.

@krdmllr

iOS is already using the UICollectionView name, that might lead to confusion and incorrect google results when searching for CollectionView. Is this a problem?

It's a problem, but not a new one. We have the same issue with GestureRecognizer, ListView, Grid, and many other things in Forms. We struggled with this a bit internally; there are only so many possible names for "a bunch of items on a screen".

"CollectionView" doesn't conflict with anything we currently have in Forms, it doesn't conflict with any UWP control names (the way "ListView" does), and it's not _exactly_ like UICollectionView (because of the "UI" prefix). It's not 100% ideal for search purposes, but we feel like it's the best expression of the intent of the control.

That said, if someone proposes an alternate name that we immediately fall in love with, I'm happy to do the search and replace.

(I wanted to name it "ListView2ColonRevengeOfTheListView", but @davidortinau shot me down :) )

@dansiegel

Some good context on this would be to think of an email client in which you may get one menu when you swipe left and another when you swipe right.

Take a look at the SwipeView spec - that's precisely what we're aiming for.

@GalaxiaGuy

support stacking icons

That's a great point, we should support that if possible. I know it works with the built-in UWP glyphs; I'd have to do a little research to make sure that type of stacking would work on the other platforms (I suspect the answer is "yes").

Update: The FontIconSource portion of this spec has been moved into its own spec.

I would a user scenario for multi-picking items from a selection, for example the selection of one or more photos from an album. Quite a common scenario in apps like OneDrive or WhatsApp.

20180527_181626000_ios

@hartez

That said, if someone proposes an alternate name that we immediately fall in love with, I'm happy to do the search and replace.

I already suggested a new name for different reasons

What will the value of the SelectedItem be when the SelectionMode is Multiple? There is 5 options I can think of:

  1. The last selected item by order of selection.
  2. The last selected item by order of source.
  3. The last selected/deselcted item by order of selection.
  4. The last selected/deselcted item by order of source.
  5. null



    (2), (3) and (4) aren't very useful. I added them just to cover all the options. (1) seems to be the most logical choice. (5) if you don't want to support SelectedItem at all if the SelectionMode is Multiple.

@AmrAlSayed0

What will the value of the SelectedItem be when the SelectionMode is Multiple?

Right now the answer is "whatever it was before you switched SelectionMode to Multiple".

@rogihee

I would a user scenario for multi-picking items from a selection

Are you asking whether this selection scenario is supported? AFAIK, all of the native controls we intend to use support it, so it _should_ be supported in CollectionView.

A bindable style for SelectionMode would be useful, if SelectionMode=None, Transparent etc, this is something Radlist does that is very useful, easy way to handle visual state based on bindings. A style for each selection mode would cover these scenarios.

@andreinitescu

Responding to your comments from https://github.com/xamarin/Xamarin.Forms/issues/3172#issuecomment-401015625 (and elsewhere):

You're bringing up a lot of good points, and I want to make sure you know we're not ignoring them. We just don't know all the answers just yet. We're in the process of spiking up this API so we can see where it works and where it falls apart; I suspect that the class breakdown you're suggesting is pretty close to where we'll need to end up.

We recognize that you (and several others) are very keen on having those intermediate classes be renderable as StackLayouts and Grids of templated items (i.e., the "BindableRepeater"), and that's one of the use cases we're exploring.

@alexhardwicke

In general in the new API, please add points where we can extend behaviour if we need to.

The UpdateX methods in the renderers will be protected virtual. :)

In all seriousness, we're aware that this has been a pain point in the past, and we're keeping it in mind while writing CollectionView.

  1. On second thought, I really don't think CollectionView is a good choice for the class name of this view.
    In Windows XAML, a CollectionView is the base class for a data source of items used for filtering grouping, see https://msdn.microsoft.com/en-us/library/system.windows.data.collectionview(v=vs.110).aspx
    Maybe at some point Xamarin Forms will get a class for same purpose, and I think it will make sense if it has same name (CollectionView), especially when thinking about XAML Standard (is this still planned?)

    As ugly and funny as it sounds, ListView2 is a good choice :) It's the recommended practice in .NET to use suffix for versioning when the existing name is the only name which makes sense:

    DO use a numeric suffix to indicate a new version of an existing API, particularly if the existing name of the API is the only name that makes sense (i.e., if it is an industry standard) and if adding any meaningful suffix (or changing the name) is not an appropriate option.

    _Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition_
    https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/general-naming-conventions

    At some point later on, everyone will use the new, shiny. stable and performant ListView2 :). Fast forward, renaming ListView2 to ListView, albeit a breaking change, will be simple (and welcome) refactoring for everybody.

  2. In Xamarin Forms there's already an ItemsView which looks very close to ItemsControl in Windows XAML, except it does not have an items layout property.
    Instead of creating a new CollectionView class, would it be possible to use existing ItemsView also as a base class for the new ListView?

  3. There's an obvious challenge in the API design and implementation, with using the native platform controls which display a list items but still have the flexibility to have something like the "BindableRepeater" which is meant to display a simple, lighter, non-scrollable and non-selectable list of items.
    Seems like Uno managed to do it:

Instead of creating a new CollectionView class, would it be possible to use existing ItemsView also as a base class for the new ListView?

There's ItemsView<T>, but we don't want to use that. It uses TemplatedItemsList, which is part of the cruft we're trying to avoid with this new control.

At some point later on, everyone will use the new, shiny. stable and performant ListView2 :). Fast forward, renaming ListView2 to ListView, albeit a breaking change, will be simple (and welcome) refactoring for everybody.

Your optimism is charming, but we have to work under the assumption that ListView(1) is forever, and that a breaking change like a ListView2 rename will not be allowed.

I thought being on par with Windows XAML makes sense, but ok, use whatever name you want, as long as the new control lives up to its promise. The Uno framework seemed to have succeeded in doing that, so now I’m eager to see what you guys are bringing in Xamarin Forms.

@gmwilhelm

https://github.com/xamarin/Xamarin.Forms/issues/3172#issuecomment-400925994

Good point. I've tentatively added that to the API. I say tentatively, because I can totally see how we might implement it on iOS and Android, but UWP might be challenging.

But I can't deny that it's both reasonable and pleasingly symmetric.

How about adding GroupItemsBinding?

That would let a Group contain a collection type property, instead of requiring that a group is derived from a collection, like the ListView does. This existing ListView limitation has forced me to do a performance costly duplication of grouped data structures on several occasions. Adding GroupItemsBinding would prevent this and allow a more flexible mapping to grouped data structures.

I.e. the example used in the GroupDisplayBinding documentation could be:

```C#
class Group // Note that Group does not have to derive from ObservableCollection
{
public Group (string firstInitial) { FirstInitial = firstInitial; }

public string FirstInitial { get; private set; }

public ObservableCollection<Person> Persons { get; set; } // We use a property for the group items instead

}

ListView CreateListView()
{
var listView = new ListView {
GroupItemsBinding = new Binding (nameof(Group.Persons))
// ...
};
// ...
}

```

Given that this is a subset of what UICollectionView does in terms of layout, I feel like we should pick a different name to avoid confusion with the capabilities in the control.

Just to be clear, this control is not available to be used yet correct? I tried to reference it but my project can't find it

@titonton This is issue is just for discussing the specification for the CollectionView, the implementation hasn't even started yet, and I don't think it will until the spec is finalized.

@AmrAlSayed0 Actually it should have started because it was moved to "In progress in Sprint 139" 11 days ago.

It's pretty unclear how this was started given it's not clear what is the decision on the API

@opcodewriter That's what I was thinking. @AmrAlSayed0 Thank you for the clarification.

Could someone clarify what the current state of this specification is? Is something missing where the community can help?

@migueldeicaza @hartez Naming this is going to be tough if you don't want it to be named CollectionView. How about CatalogView?

1

Catalogs are often designed in one or more columns and with multiple rows of items with similar fonts, texts, layouts, etc.

Sample:

022

@hartez Do you feel like the APIs are near complete now? How much work has been done on this so far? Many of us would love to get our hands on this control asap. :)

@adrianknight89 I believe this is the working branch. https://github.com/xamarin/Xamarin.Forms/tree/lv2spike

We do not anticipate it being ready for preview for a while yet, but I will showcase/demo the results of the current effort in the coming weeks to validate the progress and prompt feedback.

I'm confused. Since you've already had some internal demos, it sounds you're already quite far with implementation.
Shouldn't this mean many of the API has been nailed down? Are you following the API spec here?
I can't see how the current spec will be able to address what has been discussed here and on the other thread here https://github.com/xamarin/Xamarin.Forms/issues/1718
To be more precise, the API is not flexible enough to allow for example a simple non-scrollable and bindable StackLayout-like control.

Does the new control allow to place bound items in a stack, without scrollbar, just like StackLayout ?

Thanks long waited for this 👍

After a great deal of internal discussion and attempts to work out a suitable architecture, we have decided that CollectionView will _not_ be handling the layout scenarios discussed in #1718. In other words, it will not be handling the binding of a collection of objects to items in any Xamarin.Forms Layouts.

The original goal of the CollectionView was to allow users to easily harness the various modern native list/grid controls (UICollectionView, RecyclerView, ListView/GridView, etc.).

It was tempting to try to make CollectionView a one-stop-control for everyone's "render and arrange this template with data" needs, including all of the scenarios where the "arrange" step was handled by Forms Layouts (FlexLayout, StackLayout, etc.). And there are some obvious functionality overlaps (e.g., both scenarios use DataTemplates). But in the end, they have a big fundamental architecture difference, and attempting to bolt them together would result in something more difficult to maintain and confusing than simply leaving them as separate controls. We didn't want to create something so complex that we end up having to implement ListView3 in a couple of years. I will elaborate on that more below.

The upshot of this is that CollectionView will remain focused on the problem of allowing Forms users to utilize the native list/grid controls and benefit from their layout engines and virtualization. And #1718 will be updated to reflect an API which will allow Forms users to bind an ItemsSource and ItemTemplate to the various Forms Layout engines.

For those interested in the _why_ of two controls versus one:

The fundamental difference between what's been outlined here (as CollectionView) and the proposal in #1718 is _where_ the layout occurs.

CollectionView aims to use the native layout engines (which have been optimized heavily by the platform developers) to handle layout. Some custom code from Forms gets involved (e.g., in providing things like the SnapPoints logic on Android and iOS), but for the most part the native layout engines (and native virtualization implementations) are doing the heavy lifting. This makes a huge difference with regard to performance.

So any layout information the developer gives to CollectionView is merely passed on to the renderer on each platform for interpretation; it's effectively a specification that's translated to the local language (LinearLayoutManager/GridLayoutManager on Android, UICollectionViewFlowLayout on iOS, etc.). Beyond the DataTemplate, Forms doesn't do any of the layout work.

In contrast, a Forms Layout (FlexLayout, StackLayout, AbsoluteLayout, etc.) is laid out entirely in the Forms layer. The renderers for a Forms Layout do very little. And there's no virtualization taking place; all of the items are created and placed in the layout from the start.

Trying to bolt these two things together leads to some difficult questions, including:

  1. How does the renderer mapping work? A CollectionView using a StackLayout has a very different renderer than a CollectionView that needs to use a RecyclerView. Do we mash them together and hide the RecyclerView when we don't need it? Do we have the renderer derive from DefaultRenderer? If we do that, we always have an extra ViewGroup layer we don't really need ...

  2. How do we handle ScrollViews? UICollectionView handles its own scrolling display, but if a StackLayout needs scrolling the user normally adds it manually in Forms. Do we add another layer to insert scrolling automatically if necessary? Do we disable/remove a manually added ScrollView if the layout calls for a UICollectionView?

  3. For that matter, where do the ScrollTo methods go?

... and so on. All of these problems are _solvable_, but every solution adds _complexity_. And as has been pointed out in #1718, adding ItemsSource and ItemsTemplate to a Forms Layout is not all that difficult or complex. Making it complex just to bolt these two distinct scenarios together is not worth the benefits.

I'm confused. Since you've already had some internal demos, it sounds you're already quite far with implementation. Shouldn't this mean many of the API has been nailed down? Are you following the API spec here?

We are following the API posted here. "Quite far" is probably an overstatement; thus far we've implemented some of the non-controversial parts of the spec to verify that they're possible and that we're not going down any blind alleys. Assuming we don't run into any problems, much of what we've implemented up to this point will likely be in the released version. But everything in the spec is still subject to change, as is everything we've implemented so far.

I can't see how the current spec will be able to address what has been discussed here and on the other thread here #1718. To be more precise, the API is not flexible enough to allow for example a simple non-scrollable and bindable StackLayout-like control.

True, and part of what we've been working on is determining whether CollectionView _could_ reasonably cover those use cases. We've come to a decision on that; see https://github.com/xamarin/Xamarin.Forms/issues/3172#issuecomment-424413234.

Given that this is a subset of what UICollectionView does in terms of layout, I feel like we should pick a different name to avoid confusion with the capabilities in the control.

As I've said (https://github.com/xamarin/Xamarin.Forms/issues/3172#issuecomment-401186893), I'm open to other names.

How about CatalogView?

Catalogs are often designed in one or more columns and with multiple rows of items with similar fonts, texts, layouts, etc.

This is an interesting idea. It definitely doesn't conflict with any existing control names.

@hartez As a random guy on the internet, who is becoming more familiar with the internals of Xamarin Forms (and was already quite familiar with UITableView and UICollectionView) I think this is the right move.

Will it still be possible to provide a custom layout (even if it means providing separate implementations per platform)?

Will it still be possible to provide a custom layout (even if it means providing separate implementations per platform)?

Absolutely. You can provide your own layout marked with IItemsLayout and your custom renderer can interpret it however you want.

For example, as a proof-of-concept, I subclassed the Android renderer for CollectionView and added the ability to interpret a class FlexLayout : IItemsLayout which included a bunch of Flex Layout properties. It passes those properties on to Google's FlexBoxLayoutManager and uses that layout manager with RecyclerView. Once we make a public preview available, I'll probably throw that example up on GitHub so folks have an easy reference on how to do that sort of thing.

The aim is to make this thing very, very flexible.

@hartez
Is the problem described in https://github.com/xamarin/Xamarin.Forms/issues/3749 fixed with CollectionView?
Because here I see CollectionView has only the ItemTemplate property, which sounds like it will have same problem like ListView.

@hartez
Is the problem described in #3749 fixed with CollectionView?
Because here I see CollectionView has only the ItemTemplate property, which sounds like it will have same problem like ListView.

@andreinitescu Thanks for pointing out that discussion, I wasn't aware of this issue with DataTemplate.

I'm going to spend some time next week looking into the history of DataTemplate - why it's designed this way, and whether there are any backward-compatibility issues with fixing CreateContent to just automatically do the right thing (both in ListView and CollectionView).

@hartez Just as an example of how I worked around this issue when creating my own repeater control.

//Check to see if we have a template selector or just a template
var templateToUse = itemTemplate is DataTemplateSelector templateSelector ? templateSelector.SelectTemplate(item, null) : itemTemplate;

So in a case like that, just fixing CreateContent wouldn't break it, just make it unneeded. But I do agree with @andreinitescu that separating ItemTemplate and ItemTemplateSelector as separate properties would be ideal...probably because of my WPF and SL background.

@bmacombe IMHO, It's not only a matter of preference having it aligned to WPF/SL, it's really an issue, it creates confusion. See #3544

@andreinitescu It does create confusion :) Believe me, I was confused at first when I was trying to support DataTemplate and DataTemplateSelector in my repeater! Especially when it had an error when I assigned a DateTemplateSelector to my DataTemplate property when it worked in all the XF places that used it. Took some source code digging to figure that out. Probably isn't an issue to someone just using the built-in XF controls, but trying to do you own and use it...really confusing.

Can we have a scroll event please on CollectionView? Until CollectionView is released, I have a suggestion for ListView https://github.com/xamarin/Xamarin.Forms/issues/4323

And, will it be possible to create irregular and dynamic layouts, like PInterest by example:

You see, every image has its own height :-)

Not sure that such kind of layout can be supported ?

image

Update: from the list of name proposals, the closest that we have come up with is "ItemsView", this is to avoid using the term "CollectionView" that gives folks the impression that this is as complete as the iOS "UICollectionView"

Hi, I'm still new to Xamarin, but have been working with ListView by using DataTemplateSelector.
When I tried to test out using CollectionView with DataTemplateSelector , it throws error

Unhandled Exception:

System.InvalidOperationException: LoadTemplate should not be null occurred

Is there a known bug related to DataTemplateSelector?
I could be implementing it wrongly. Is there any example on using DataTemplateSelector with CollectionView?

@hartez @davidortinau any reason why KeepItemsInView is not named KeepFirstItemInView to align with KeepLastItemInView? The current name is plural (i.e. suggests multiple items) whereas the description says it only keeps the first visible item in the viewport.

Also, is there a way you could expose an API to get the list of views currently in the viewport? The other night, I was working on creating a video view to be embedded in a ListView cell and autoplayed/paused based on viewport visibility, but it was near impossible with the current ItemAppearing and ItemDisappearing events especially when they kept firing in all kinds of unexpected ways with cell recycling and/or fast scrolling. Really looking forward to CollectionView supporting this kind of functionality in a more reliable way.

autoplayvideos demo

Another thing that would be great to have is the ability to create a dependent, minimized view that is detached from the parent while the user has the luxury of scrolling on the current feed. I've seen this on YouTube as we're now able to continue watching the current video while having the ability to continue browsing around. I'm not sure if this is something CollectionView can or should support btw, but it's something to think about.

youtube1-5abab8210e23d9003787855d

So i played around with the current nightly build a bit (4.0.1.43780-nightly) which resolved some resizing issues compared to the current preview build.

A suggestion i have would is to add something like RowSpacing/ColumnSpacing or GridSpacing to grid layouts since that makes it much easier to space your items correctly without using margin/padding on the individual items.
Another thing would be to add Padding or maybe EdgeOffset to the CollectionView or Layout to avoid using Margin, which cuts of the items like shown here:
android-margin-image
Margin also crops the "drag" animation on Android like you can see here:
android-margin

A suggestion i have would is to add something like RowSpacing/ColumnSpacing or GridSpacing to grid layouts since that makes it much easier to space your items correctly without using margin/padding on the individual items.

Agreed, and that's on our radar - see #4681.

Update: from the list of name proposals, the closest that we have come up with is "ItemsView", this is to avoid using the term "CollectionView" that gives folks the impression that this is as complete as the iOS "UICollectionView"

what about "FloatView" ?

Beside ItemAppearing/Disappearing events mentioned above, any plans for ways to get view for an item:
View GetView(object item)
If item is not materialized it should return null I guess.

I'm using a Vertical List and there seems to be inconstancies in how it's rendered on iOS vs Android.

On iOS, with the label will take up 100% of the width.
screenshot 2019-01-15 13 56 01

On Android, it will only take up it's content width.
screenshot 2019-01-15 13 57 59

I could only get it to layout correctly with a static width definition.
Is there an Android workaround that respects the Grid Width="Auto" property?

I'm using a Vertical List and there seems to be inconstancies in how it's rendered on iOS vs Android.

@shwanton Please open a separate issue for this bug, and I'll take a look.

@shwanton i had similiar issues which got fixed when i switched to the nightly feed

@krdmllr I can confirm, it has been fixed in the latest build. Thank you.

Hi. Will there be ItemTapped event in CollectionView similar to ListView's ItemTapped? I don't see it in the spec. Thank you.

@uvirra There is an existing issue for your DataTemplateSelector inquiry. See #4826.

@hartez Will there ever be a need for an item recycling strategy like the three ones that exist for ListView? You did mention several times native virtualization that CollectionView leverages. I just want to get more clarification on this.

I'm also curious to know how RefreshView will look on iOS. The current refresher for ListView requires UITableView's Bounces property to be turned on whereas, on Android, the refresh view is pulled on top of the top most visible item (which I personally prefer).

@hartez Will there ever be a need for an item recycling strategy like the three ones that exist for ListView? You did mention several times native virtualization that CollectionView leverages. I just want to get more clarification on this.

The current design does not call for anything like recycling strategy. Right now, we are simply utilizing the virtualization provided by the native controls, which do a very good job of it out of the box.

Will there ever be a need? My hope is "no", and we'll do our best to avoid it because it adds a lot of complexity (both for users and for maintenance). If we do eventually conclude that we need something like that, we'll be approaching the design very, very carefully.

What about the scrolled event? Most of the modern UI/UX provide parallax header, show/hide items (buttons, headers, filters, ecc..) on scrolling and similar.
I think that a new, amazing, control like this should support modern scenarios.

it shouldnt be a problem, both recyclerview and UICollectionview support the scrolled event out of the box.

Even the Carouselview (based on collectionview) support the scrolled event with direction, scrolling value and delta: https://github.com/xamarin/Xamarin.Forms/issues/4996

To follow up on @Evolutionlab's comment on this being a new amazing control that should support modern scenarios, I would like to see even better virtualization support.

https://docs.microsoft.com/en-us/windows/uwp/debug-test-perf/listview-and-gridview-data-optimization

If this is too much to grasp I would like to get access to VisibleItems so that I can do virtualization in my ViewModel instead.

Keep up the great work!

@hartez I was just thinking it would be cool to let developers define a minimum/maximum threshold on the number of selected items. I'm currently making a custom photo gallery that should not allow more than 5 photos to be selected. When the threshold is reached, tap events on cells should be ignored unless they are unselecting items.

This could also be done by setting SelectedItems (which hasn't been implemented yet) on SelectionChanged event based on CurrentSelection count, but this is going to trigger SelectionChanged twice. In my opinion, we should have a way to proactively control selection behavior before anything reaches Core.

Playing with CollectionView a bit today, I noticed UWP is a lot farther behind then Android and iOS, which I under why.

Just want to confirm it's planned to have full UWP support when finalized?

Beside ItemAppearing/Disappearing events mentioned above, any plans for ways to get view for an item:
View GetView(object item)
If item is not materialized it should return null I guess.

What about ItemAppearing? I don't see any news about it

I was playing around with the CollectionView and was facing problems with uneven row height. I saw there was a ItemSizingStrategy introduced lately, but it's still behaving weird though.

I played around with the DataTemplateGallery and when switching to MeasureAllItems I get the following result (iPhone 6, iOS 12.1.4):

After swiping to the right and coming back the result changes to:

@hartez Is this expected to work or still work in progress (couldn't find any issue for that)?

Is RemainingItemsThresholdReached been implemented yet?

It is not available on the CollectionView control XAML in 4.0.0.169046-pre5.

Can any one tell me RemainingItemsThresholdReached is part of 4.0 Release? If yes, can you please give sample code on how to use that feature.

@Dresel Can you open a new ticket if you think this is a bug? It's better if it gets tracked.

@melucas @chandrubk I don't think RemainingItemsThresholdReached is being worked on yet.

https://github.com/xamarin/Xamarin.Forms/branches/all

I too would like to see this feature (along with the Refresh view) implemented soon as I can't touch CollectionView without it.

4323

We need the Scrolled Event like ScrollView do

regards,

4323

We need the Scrolled Event like ScrollView do

regards,

I support this.
Moreover, it would be awesome to get and event when the scrolling is stopped/finished.

In IOS, the UICollectionview is a subclass of UIScrollview, so we can get scrollViewDidEndDecelerating from the UIScrollViewDelegate

In Android i think we can extend the RecyclerView.OnScrollListener ?

This will open more advanced and polished scenarios for custom refreshing, parallax, syncronized scrolling elements, ecc..

Any chance of there being out of the box animation for Android, like that of the Recycler View?

Any chance of there being out of the box animation for Android, like that of the Recycler View?

Which animations are you referring to? The Android renderer for this is built on RecyclerView, so it already uses the default animations for things like adding/removing items.

Hi,

I am using 4.0.0.304370-pre8.
The example from (link below) does not display anything on UWP, when using CarouselView.
But CollectionView displays the list. Are there any specific configuration needed to enable CarouselView for UWP?

https://devblogs.microsoft.com/xamarin/xamarin-forms-4-0-feature-preview-an-entirely-new-point-of-collectionview/

Thanks.

Hi @noypi,

While CollectionView can technically "work" to a rather small degree on UWP, the full implementation of CollectionView and CarouselView are strictly being done on Android and iOS to start with. No official work for UWP is scheduled at this time, but we're continuously collecting feedback. If you would like to discuss what sort of work you're doing on UWP in particular, you can send me an email at paul.[email protected].

According to the spec, will TableView be replaced by CollectionView entirely?

Another question: since there're no cells anymore, how to add a disclorure indicator for iOS? With ListView it was possible via custom renderer.

According to the spec, will TableView be replaced by CollectionView entirely?

TableView will still exist. We won't be removing any existing controls.

Another question: since there're no cells anymore, how to add a disclorure indicator for iOS? With ListView it was possible via custom renderer.

On iOS, CollectionView renders using a UICollectionView, which means that its cells are UICollectionViewCells. And UICollectionViewCells don't have accessory views (like disclosure indicators). So for any UI elements like disclosure indicators or checkmarks, you would need to create those in your ItemTemplate.

How to disable selection on certain types of items? I have multiple data templates and want to disable selection on some of them.

@hartez When setting ItemTemplate to DataTemplateSelector im getting exception: System.InvalidOperationException: LoadTemplate should not be null

I thought that templates will be supported out of the box

@hartez When setting ItemTemplate to DataTemplateSelector im getting exception:System.InvalidOperationException: LoadTemplate should not be null

I thought that templates will be supported out of the box

They should be; perhaps you're encountering a bug. Please open an issue so we can investigate.

@toomasz Before opening an issue, can you please update your Nuget to the latest pre-release (or the nightly) and test the selector again? The issue you're seeing was present when there was no support for DataTemplateSelector.

@hartez Is any work currently being made on the header&footer as well as the refresh view? If I can free up time, I might look into either one, but I want to make sure I'm not stepping on your toes.

@adrianknight89 It works on 4.0! Awesome

@hartez Is any work currently being made on the header&footer as well as the refresh view? If I can free up time, I might look into either one, but I want to make sure I'm not stepping on your toes.

Nothing's being done at the moment - if you want to take a crack at it, that'd be great.
Just a heads-up, after some discussion today we've added two new properties related to header and footer - IsHeaderSticky and IsFooterSticky, for specifying whether they scroll with the items or remain in place. If you want to tackle those along with the header/footer, that would be awesome, but it would also be great if we had them working one way or the other and could implement those properties later.

Is there a plan to support collection view on UWP?

Yes. The implementation is a little behind the other platforms right now, but the plan is to fully support it. You can follow the feature progress at https://gist.github.com/hartez/7d0edd4182dbc7de65cebc6c67f72e14

Any info on RefreshView?
I have the latest Xamarin 4 beta version and the RefreshView type cannot be found

Any info on RefreshView?
I have the latest Xamarin 4 beta version and the RefreshView type cannot be found

RefreshView has not been implemented yet. You can track the feature progress here.

Add GroupItemsBinding ?

How about adding a GroupItemsBinding property to specify which property contains the child items of a group? That would allow to embed a child collection property instead of forcing groups to inherit from a collection.

Advantages:

  • Ability to (de)serialize the grouped collection to/from JSON.
    Inheriting groups from a collection blocks JSON (de)serialization (because JSON arrays only support a range of values and not properties). (De)serializing viewmodels is needed to preserve viewmodel state when the app goes to background, or if your app API sends you viewmodels. The current workaround is to have a second data structure and do a costly duplicate + transform on each data update.
  • Ability to use your own base class for group items (e.g. ViewModelBase)
  • Avoid polluting group objects with all inherited properties of a collection

E.g. you could write this grouping example from docs.microsoft.com:
```C#
public class PageTypeGroup : List
{
public string Title { get; set; }
// More properties ...
}

like this instead:

```C#
public class PageTypeGroup
{
    public string Title { get; set; }
    // More properties ...

    public List<PageModel> Children { get; set; }
}

with XAML:

C# <CollectionView GroupItemsBinding = "{Binding Children}" ...> </CollectionView>

Not specifying GroupItemsBinding would be compatible with the existing implementation, equivalent to GroupItemsBinding="{Binding .}"

P.S. I submitted this proposal earlier, in Jul 2018.

Update Aug 23 2019: grouping has been implemented but without this fix; see Group data

I hope it is not too late to add this.

How about supporting multiple grouping levels?
Would allow to display trees.

E.g. Flutter has ExpansionTile (example)

Regarding the CollectionView, I've come across a problem that I think would be a great feature to add.

In a Horizontal List, with scroll, typically designers, add a "shadow" effect on the elements that are not totally visible in the screen. Currently (as far as I know) there is no way to do this in Xamarin.Forms. Wouldn't you think this would be a niec to have feature? It could be as simple as a boolean, that would apply a "drop shadow" to the element that is visible only by a X percentage, for example.

I propose a Position property. This property would hold the index of the current item. This would allow easy integration of ViewPagerIndicator and similar indicators.

I understand determining the "current item" can be tricky. If snapping is on, it should be pretty easy to determine to which item the view is snapped. Without snapping the correct choice would depend on use-case: perhaps it would be the item occupying the start or the midpoint of the view.

This property could also allow easy two-way access as an alternative to ScrollTo().

@hartez We were expecting this to be ready for the 4.0 release but surprised to see it isn't finished yet. We can't test CollectionView without scroll and refresh functionality. Can you tell us how many sprints we need to wait before they are rolled out? We've decided not to ship anything with ListView going forward and would like this control to be available as soon as possible.

@hartez We need a way for CollectionView with list layout to size to its items contents. i think it's a common use case:
image
In this exaple buttons should be directly below collection view. I think it should work this way when VerticalOptions is Start

when remaining items threshold reached property test

I have questions on if the CollectionView flow of an individual item behavior mimics iOS Native behavior when it comes to screen size changes. I'll give you an example:

A image gallery cell in iOS is created with a CollectionView and you define an individual cell. The out of the box behavior is that how many cells draw in a single row is dynamic based on the screen size. On a phone I might fit 4 items but on a tablet I could fit maybe 8 or 9.

Will the Forms version also offer this? So far the example I've read I've only seen where you set the GridItemsLayout Span property. This results in a hard coded value of how many items can draw and really in the world of various screen sizes hard coding seems so 2014. :-P

UWP have four selection mode state
{
None,
Single
Multiple,
Extend,
}
image

image

I think Four state in Android and IOS are also useful
Just take a look at the File explorer
image

Are there any plans for a simple padding property? #6605 For my particular use case I could probably use an appropriately sized blank header and footer (once those features have been developed), but that would be a bit of a hack and not suitable for a grid layout where padding on all four sides may be required.

Any plan to rearrange list item in collection view.

Does the spec cover how to disable selection for particular items in CollectionView?

// Any possible API could be helpful
private void OnSelectionChanging(object sender, SelectionChangingEventArgs e)
{
  if (...)
      e.Cancel = true;
 }

Currently i work-around it but this does not prevent the Selected VisualState to be applied.

void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    // Deselect the item.
    if (sender is CollectionView cv && e.CurrentSelection...)
    {
        cv.SelectedItem = null;
    }
}

Vertical Scrollbar Color and Horizontal ScrollBar Color would be great!

What about the direction of scrolling, I mean begin scroll from Right to Left, not the content itself

I would like to have separators...

It would be great to have possibility to "memoize" and apply scroll position.

What would be so amazing, would be a possibility to use different item templates for every second or X item. This would make it possible to create a gray background for every second item and many other styling possibilities.

Can you not do that with template selector already? Using position with
modulo operator?

On Tue, Aug 13, 2019, 16:53 Legacyorder notifications@github.com wrote:

What would be so amazing, would be a possibility to use different item
templates for every second or X item. This would make it possible to create
a gray background for every second item and many other styling
possibilities.


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/xamarin/Xamarin.Forms/issues/3172?email_source=notifications&email_token=AC4YCKDFCH3WFENRCLPWEC3QELDE3A5CNFSM4FHJRXPKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD4F5IQA#issuecomment-520868928,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AC4YCKHXX5YSR7M3S4VU5QLQELDE3ANCNFSM4FHJRXPA
.

Circular Scrolling whould be nice. I guess it's easy to implement.

I would like to have an "AbsoluteItemsLayout" as ItemsLayout for the CollectionView to make it possible to set absolute positions in a list, at the moment i see no other solution rather then doing it in code behind.

Is it possible, when using GridItemsLayout, to allow items to span over multiple rows or columns? That would definitely be a feature that would be worth having.

Can you guys also expose the Scrolled event to this control? The purpose of that is when I reach the bottom of the list, I want to reload additional items. I don't know if CollectionView detects if its inside the ScrollView and it disables the scrolling capability.

Can you guys also expose the Scrolled event to this control? The purpose of that is when I reach the bottom of the list, I want to reload additional items. I don't know if CollectionView detects if its inside the ScrollView and it disables the scrolling capability.

Your wish is granted! Check version 4.2 :)
https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/collectionview/scrolling

You should not include a CollectionView inside a ScrollView, or virtualization won't work.

Can you guys also expose the Scrolled event to this control? The purpose of that is when I reach the bottom of the list, I want to reload additional items. I don't know if CollectionView detects if its inside the ScrollView and it disables the scrolling capability.

Your wish is granted! Check version 4.2 :)
https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/collectionview/scrolling

You should not include a CollectionView inside a ScrollView, or virtualization won't work.

I'm in 4.2.0.709249
am I missing something?
image

image

I do have the Scrolled event with 4.2.0.709249.
Try to delete bin/obj folders and check NuGet consolidation to be sure.

Do we get RTL support soon with 4.2 for Android and iOS ?

Do we get RTL support soon with 4.2 for Android and iOS ?

Some support is already there; FlowDirection support should already be working within CollectionView items. What's still incomplete is the scroll direction for horizontal CollectionView layouts. The scroll direction should match the FlowDirection on Android, but we still have some work to do on that for the other platforms; that work is targeted for completion in 4.3.

If you run into any bugs using FlowDirection with the CollectionView, please open an issue and we'll take a look.

Can you please describe what is not done with RTL support?
Because in spec, it is not even not marked as in progress or complete.

On Thu, 5 Sep 2019, 2:19 a.m. E.Z. Hart, notifications@github.com wrote:

Do we get RTL support soon with 4.2 for Android and iOS ?

Some support is already there; FlowDirection support should already be
working within CollectionView items. What's still incomplete is the scroll
direction for horizontal CollectionView layouts. The scroll direction
should match the FlowDirection on Android, but we still have some work to
do on that for the other platforms.

If you run into any bugs using FlowDirection with the CollectionView,
please open an issue and we'll take a look.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/xamarin/Xamarin.Forms/issues/3172?email_source=notifications&email_token=ACDWB3GSYAQSADERHWVTJX3QIANMNA5CNFSM4FHJRXPKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD5455TA#issuecomment-528080588,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ACDWB3HMFCHBRZWD5AJMXH3QIANMNANCNFSM4FHJRXPA
.

Not done: Scroll direction for horizontal layouts.

If you set FlowDirection = RightToLeft on a horizontally scrolling CollectionView, the scroll direction will not be right-to-left on iOS and UWP right now (I believe it _does_ work on Android).

How about some LoadingDataTemplate?

From my experience loading data async into ListView/CollectionView there may sometimes be empty space until the listview/collectionview is populated.

Adding LoadingDataTemplate can provide additional responsiveness when large data is being populated and the page has already appeared.

I think there are two ways a loading indicator is used. One is when the CollectionView is initially displayed. Multiple placeholder cells are shown until the data is added to the ItemsSource collection. The second one is when more data is added at the bottom of the list. For the second one, I think we can leverage the footer?

The first one requires more work (e.g. initially load the source with 3-5 items that have the same placeholder data template and then remove those items and add the actual data when it's fetched). Another approach is to put a skeleton view on top of CollectionView and hide it when data is ready. I currently follow this approach with ListView.

I have not tried this, but we could set EmptyView to the loading view first and if there are no results, change the template for the EmptyView to show a "nothing found" message.

@adrianknight89

Another approach is to put a skeleton view on top of CollectionView and hide it when data is ready. I currently follow this approach with ListView.

This sounds like the same method I follow as well i.e. put some activity indicator above. Set ListView to IsVisible = false and ActivityIndicator IsVisible = true, then invert both values after listview populated.

@adrianknight89

I have not tried this, but we could set EmptyView to the loading view first and if there are no results, change the template for the EmptyView to show a "nothing found" message.

Theres an idea! While that might work I do feel it would be better simplified to have seperate template properties on CollectionView concerning LoadingDataTemplate and EmptyView.

I agree that it'd be better to have two different properties. Other than the simplicity aspect, using a single property for two different purposes does not make a lot of sense. Maybe EmptyView should have been named BackgroundView so we get to use it for whatever purpose. (Edit: A BackgroundView is an entirely different thing.)

@LeoJHarris I added #7447 for BackgroundView support. We could use EmptyView and BackgroundView to support the above two scenarios though this isn't still 100% what you want, but it should be better than using EmptyView to support both scenarios. You could use BackgroundView as a loading screen and null it out when data is ready.

@adrianknight89 it would be great if CollectionView handled the 'null it out' once data is ready rather then manually controlling this (unless you are already implying that).

When scrolling quickly through a page that utilizes CollectionView's RemainingItemsThreshold we are experiencing two different issues.

  1. The app freezes and must be force quit
  2. The items in the CollectionView stack on top of each other (see image)

Haven't been able to find anybody else having this issue. Have you seen it reported?

@Bronson15 How are you handling the RemainingItemsThresholdReached event? Quick scrolling will trigger it several times and so you need to ignore event calls while you're waiting to update your data source otherwise they will pile up. Also, try updating your UI on the main thread.

If you're still having trouble, you could open a new issue with a repro for investigation.

@Bronson15 both issues.
Tried with ObservableRangeCollection and fixed #2.
Still having issues on freezes / blank list: when running on emulator I see cpu spike, seems an infinite loop.

Edit: breaks only on iOS, on Android works fine.

Hi Team,
Even I tried to use RemainingItemsThreshold and RemainingItemsThresholdReachedCommand and noticed that function assigned to RemainingItemsThresholdReachedCommand gets called multiple times sequentially (first time it gets called twice, next time 4 times etc.) even if I don't scroll quickly. I'm also able to reproduce it with fresh Xamarin Forms project (v.4.2.0.778463).
Can you try to reproduce it at your end? Here's the simple code snippet below:

XAML:

<CollectionView
        x:Name="StackLayout"
        ItemsSource="{Binding LatestStories}"
        RemainingItemsThreshold="10"
        RemainingItemsThresholdReachedCommand="{Binding RemainingStoriesCommand}">
        <CollectionView.ItemTemplate>
            <DataTemplate>
            <Grid
                                ColumnSpacing="16"
                                HeightRequest="110"
                                RowSpacing="0">

                    <Grid.RowDefinitions>
                        <RowDefinition Height="*" />
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="*">
                        </ColumnDefinition>
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>

                    <!--  Blog title  -->
                    <Label
                                    Grid.Column="1"
                                    Margin="0,8"
                                    FontSize="14"
                                    LineBreakMode="TailTruncation"
                                    LineHeight="{OnPlatform Default=-1,
                                                            Android=1.25,
                                                            iOS=1.25}"
                                    MaxLines="2"
                                    Text="{Binding Title}" />

                    <!--  Author name  -->
                    <Label
                                    Grid.Row="1"
                                    Grid.Column="1"
                                    Margin="0,8,0,0"
                                    FontSize="12"
                                    LineHeight="{OnPlatform Default=-1,
                                                            Android=1.5}"
                                    Text="{Binding Author}" />

                </Grid>
            </DataTemplate>
        </CollectionView.ItemTemplate>
</CollectionView>

View Model:

public class ArticleListViewModel
    {
        public ObservableRangeCollection<FeedItem> LatestStories { get; } = new ObservableRangeCollection<FeedItem>();
        public Command RemainingStoriesCommand => new Command(() => RemainingStories());

        public ArticleListViewModel()
        {
            RemainingStories();
        }

        private async void RemainingStories()
        {
            var feeds = await GetRemoteFeedsAsync();
            try
            {
                Device.BeginInvokeOnMainThread(() =>
                {
                    LatestStories.AddRange(feeds);
                });

            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex, "");
            }
        }

        private async Task<List<FeedItem>> GetRemoteFeedsAsync()
        {
            try
            {
                Stopwatch watch = new Stopwatch();
                watch.Start();
                var allItems = new List<FeedItem>();
                HttpResponseMessage response;
                var httpClient = new HttpClient();
                response = await httpClient.GetAsync("https://jsonplaceholder.typicode.com/photos").ConfigureAwait(false);
                if (response.IsSuccessStatusCode)
                {
                    var data = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
                    var testData = JsonConvert.DeserializeObject<List<TestJson>>(data);
                    if (LatestStories.Count == 0)
                    {
                        testData = testData.Take(20).ToList();
                    }
                    else
                    {
                        testData = testData.Skip(LatestStories.Count).Take(20).ToList();
                    }

                    foreach (var item in testData)
                    {
                        var newItem = new FeedItem
                        {
                            Title = item.id.ToString(),
                            Description = item.title,
                            ImagePath = item.thumbnailUrl,
                            Link = item.url,
                            PublishDate = "2019-09-11",
                            Category = ""
                        };
                        allItems.Add(newItem);
                    }
                }
                watch.Stop();
                Debug.WriteLine("TPL Total Time: " + watch.ElapsedMilliseconds);
                return allItems;
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex, "");
                throw;
            }

        }
    }

@Bronson15 @andreabalducci @techduggu Since we don't block UI while RemainingItemsThresholdReachedCommand is being processed, it is normal to keep hitting the command several times due to your scroll patterns. Please see how I handle the issue with a locking mechanism: https://github.com/xamarin/Xamarin.Forms/pull/7516/files#diff-2be3eff4d53f761cd581cca1d2ec3bc0R48

Other ways to do this is enable/disable your command or unsubscribe/subscribe the event while remote fetching is in progress. In my experience, having a semaphore worked the best because sometimes multiple invocations are fired by the time you try to enable/disable or unsubscribe/subscribe the callback.

@hartez @samhouts @davidortinau I think this issue will come up pretty often in the future. Should the suggestion above be part of the documentation for remaining items? I'd have the docs team create a remote feed for testing and recommend a coding pattern for reference so people don't keep asking for help.

@techduggu There are different (minor) issues with your code. I'd get it code reviewed on Stack Exchange. This is not the place for that now.

@adrianknight89 Thank you for highlighting the term "due to your scroll patterns". This triggered my itch about finding more about it. After going through official documentation of RecyclerView and few other resources, Yes, I can confirm that it gets called multiple times due to scroll patterns and those patterns are SCROLL_STATE_IDLE, SCROLL_STATE_DRAGGING or SCROLL_STATE_SETTLING depending upon our scrolling state.
https://developer.android.com/reference/android/support/v7/widget/RecyclerView.OnScrollListener

Your code and this android guide (https://github.com/codepath/android_guides/wiki/Endless-Scrolling-with-AdapterViews-and-RecyclerView) also confirms the same that we should be handling infinite scrolling either via locking or making use of the above scroll states (which mostly requires custom renderer). Hence with Xamarin.Forms, I've tried your code and it worked like charm. :) I would recommend and support your opinion to include this suggestion as part of docs to avoid such issues raised by people (with half-knowledge) like me. :)

Also, reg. the minor issues you mentioned for the above code snippet - Well this is just a POC project for testing the infinite loading with Collection View, however I'd love to know your input if you've noticed anything apart from silly null check etc.

Thanks!

@adrianknight89 Ah yes. Our Busy check was missing and that helped with the stacking issue.

I also implemented the Semaphore as you suggested and it seems to have mitigated an issue where when adding new items to the ItemsSource the view would reset scroll position to the beginning. Oddly enough, adding the call in a try; finally; like you did in your test file brought this issue back.

Still having a freeze issue when scrolling to the end of the list. The view goes blank and the application freezes.

Edit: Scroll position reset is still there, but not as often. The rendering of loading more items is very choppy on device as well.

@techduggu I don't have VS with me, but just looking at the code, you should await RemainingStories(), move the remote call inside the try, and use a using for HttpClient (ideally use a single static instance across your application and never dispose it), but I'll stop here. :)

@Bronson15 There was an issue with CollectionView that reset scroll position and caused UI freezing. I think it was fixed with #7285, but that's iOS only. Can you test the latest nightly Nuget and see if you're still having trouble? Nightly feed URL is on the GitHub homepage for Forms. If problems persist, please open an issue with reproduction code so we can take a look.

@adrianknight89 Scrolling through with the nightly build. Seems like the issue is mostly fixed (I did see it happen once). It seems like the list is just in an endless loop now though instead of having an end. AFAIK there's no property in the spec to stop that from happening?

@Bronson15 Endless loop should not happen. Are you seeing it on iOS or Android? You need to end the loop when you reach the end of your remote feed (i.e. return from RemainingItemsThresholdReachedCommand immediately without issuing another DB call).

Once the view scrolling stops, the command should no longer be triggered. I use Azure Cosmos that returns a continuation token. When the token is null, I know that there is no more content to load, so my RemainingItemsThresholdReachedCommand works based off of that token. You should implement something similar.

@adrianknight89 Ahhh. Interesting. Added a check for result count and returning if it is 0. Fixed the infinite scroll. Thank you for the help!

@adrianknight89 tested nighly for iOS crash issue, it finally works. still "a lot" slower than Android.
with 1000 items on Android is almost real-time, on iOS have to wait 5-7 seconds to have the view rendered. both debug, iPhone Xs and Redmi Note 7

@andreabalducci Are you on the XS simulator? How is the behavior on a physical device? If view rendering is slow, this may be another issue with iOS that needs to be investigated. Again, it'd be great to see a repro.

@adrianknight89 @andreabalducci yeah it takes about 1-5 seconds on my Xs Max to load more items. The view blanks out and re-loads all items rather than adding items to the already rendered list.

@adrianknight89 both physical devices, iOS emulator has the same issues.

We removed all stacklayout from datatemplates and gained some speed switching to FormattedString, enabled compiled bindings, before iOS was over 20 seconds.

On iOS the view blacks and redraw all when adding on the ObservableRangeCollection (from mvvm helpers), on Android works fine.

This sounds like a separate issue to me. I don't think it's remaining items related.

Is it possible, when using GridItemsLayout, to allow items to span over multiple rows or columns? That would definitely be a feature that would be worth having.

Any information on this?

@LynoDesu An issue is being tracked for this: https://github.com/xamarin/Xamarin.Forms/issues/6357

@LynoDesu An issue is being tracked for this: #6357

Ah, great! Thanks. Where do i get started if I want to contribute to this?

Read the homepage wiki as well as Contributing.md.

@adrianknight89 found the blank + back to start issue, repro here https://github.com/andreabalducci/XamarinCollectionView/blob/b186e563ff8391dfb473e62e5a4c4587e8d4e9da/cvrepro/cvrepro/ListViewModel.cs#L46

Starting with an empty collection triggers the issue, if collection has any items before binding all works as expected.

tested on iPhone emulator.

I see the issue. This is probably the same as #7548. You might want to post your repro over there.

CollectionView seems to be bugged on Android when using IsGrouped.

CollectionView.GroupHeaderTemplate is not rendered at all. On iOS it works fine. You could just use the grouping example from the Microsoft site to test it out.

    public class AnimalGroup : List<Animal>
    {
        public string Name { get; private set; }

        public AnimalGroup(string name, List<Animal> animals) : base(animals)
        {
            Name = name;
        }
    }

    public class Animal
    {
        public string Name { get; set; }
        public string Location { get; set; }
        public string Details { get; set; }
        public string ImageUrl { get; set; }
    }

    public List<AnimalGroup> Animals { get; private set; } = new List<AnimalGroup>();

    Animals.Add(new AnimalGroup("Bears", new List<Animal>
        {
            new Animal
            {
                Name = "American Black Bear",
                Location = "North America",
                Details = "Details about the bear go here.",
                ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/0/08/01_Schwarzbär.jpg"
            },
            new Animal
            {
                Name = "Asian Black Bear",
                Location = "Asia",
                Details = "Details about the bear go here.",
                ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b7/Ursus_thibetanus_3_%28Wroclaw_zoo%29.JPG/180px-Ursus_thibetanus_3_%28Wroclaw_zoo%29.JPG"
            },
        }));
<CollectionView ItemsSource="{Binding Animals}"
                        IsGrouped="true">
            <CollectionView.GroupHeaderTemplate>
                <DataTemplate>
                    <Label Text="Header"
                           BackgroundColor="LightGray"
                           FontSize="Large"
                           FontAttributes="Bold" />
                </DataTemplate>
            </CollectionView.GroupHeaderTemplate>
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <Grid Padding="10">
                        <Image Grid.RowSpan="2"
                               Source="{Binding ImageUrl}"
                               Aspect="AspectFill"
                               HeightRequest="60"
                               WidthRequest="60" />
                        <Label Grid.Column="1"
                               Text="{Binding Name}"
                               FontAttributes="Bold" />
                        <Label Grid.Row="1"
                               Grid.Column="1"
                               Text="Child"
                               FontAttributes="Italic"
                               VerticalOptions="End" />
                    </Grid>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>

https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/collectionview/grouping

Important

Grouping data with CollectionView is currently only supported on iOS.

Ops, I missed that part. Thanks.

For those of us who want to display a grouped list on both iOS and Android, but want to avoid ListView, is there anything else that we can use that’s as flexible as the CollectionView for now? Or are we stuck with ListView?

I hope this is the right place to ask. I see in the original posted spec there are properties for IsHeaderSticky and IsFooterSticky, but I don't see any further mention of them anywhere in the discussion or the implemented source code. Are those still on the roadmap for this view?

In collectionview we need ItemAppeared, ITemDisappeared.
is there any way to achieve ?

@IosDeveloperHarsh The Scrolled event provides a lot of useful information in the event args. Look at first and last visible item indexes there.

@rafiwardak2003 Gallery samples with CollectionView groups work on Android as of today though I haven't run the sample you've provided. Which Nuget were you using? Try with the latest pre-release or nightly.

@cabal95 I'm not qualified to answer this, but if I had to guess they will eventually be implemented. Perhaps, we need to have an active issue to track this. I do know that the initial header/footer work excluded sticky stuff.

I think that SelectionChangedCommandParameter should be removed and instead we will have the selected item automatically set as a parameter.

If it is possible it would be nice to use the property like this

public ICommand => new Command<MySelectedItemModel>((item) => {}

But this should be ok as well:

public ICommand => new Command<object>((item) =>{ var selectedItem = item as MySelectedItemModel;}

I think that SelectionChangedCommandParameter should be removed and instead we will have the selected item automatically set as a parameter.

If it is possible it would be nice to use the property like this

public ICommand => new Command<MySelectedItemModel>((item) => {}

But this should be ok as well:

public ICommand => new Command<object>((item) =>{ var selectedItem = item as MySelectedItemModel;}

What if the user wants to use something other than the SelectedItem as the parameter to their Command?

I think that SelectionChangedCommandParameter should be removed and instead we will have the selected item automatically set as a parameter.
If it is possible it would be nice to use the property like this
public ICommand => new Command<MySelectedItemModel>((item) => {}
But this should be ok as well:
public ICommand => new Command<object>((item) =>{ var selectedItem = item as MySelectedItemModel;}

What if the user wants to use something other than the SelectedItem as the parameter to their Command?

You have a point, but I have hard to see a use case for that because you are setting the parameter on CollectionView level. I expected that it to be the selected item the first time I used it. But you maybe can set the selected item as default? If you use the event you will get so I think many developers expect it for the command as well.

I'd like to also request for a feature that this CollectionView does not stretch up on the entire screen and just use the height depends on the number of item.

I am trying to have a multple lists in view
i.e
Purchases

Deductions

Total
total
tot

but Items 1 and 2 (a CollectionView) just took too much height even if the I only have 3 or 4 items and there is a BIIIIIIIIIIIIIIIG gap below before I can see the Deductions section

I ended up making my own ItemsCollection control based on StackLayout

I'd like to also request for a feature that this CollectionView does not stretch up on the entire screen and just use the height depends on the number of item.
I ended up making my own ItemsCollection control based on StackLayout

I think what you are looking for may be Bindable Layouts.

I'd like to also request for a feature that this CollectionView does not stretch up on the entire screen and just use the height depends on the number of item.
I ended up making my own ItemsCollection control based on StackLayout

I think what you are looking for may be Bindable Layouts.

Hey! Exactly what I need. Since when BindableLayouts existed?

Thank you everyone for the discussion on this issue! If you have any additional feature requests or bug reports, please open new issues for each one. We are now closing this issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

simontocknell picture simontocknell  ·  3Comments

xabre picture xabre  ·  3Comments

Hudhud picture Hudhud  ·  3Comments

EmilAlipiev picture EmilAlipiev  ·  3Comments

Papirosnik picture Papirosnik  ·  3Comments