Add support for sticky group headers (iOS, Android)
This feature is available in the ListView control. E.g. On iOS using the built-in CollectionView it can be added this way:
public class CollectionViewPlatformHandler : CollectionViewHandler { /// <inheritdoc /> protected override ItemsViewLayout SelectLayout() { var layout = base.SelectLayout(); if (ItemsView.IsGrouped && layout is UICollectionViewFlowLayout flowLayout) { // Enable sticky section headers. flowLayout.SectionHeadersPinToVisibleBounds = true; } return layout; } }
Add support for scrollable index titles (iOS).
This feature is available in the ListView control. E.g. On iOS using the built-in CollectionView it can be added this way:
public class CollectionViewPlatformHandler : CollectionViewHandler
{
/// <inheritdoc />
protected override UIView CreatePlatformView()
{
var platformView = base.CreatePlatformView();
if (ItemsView.IsGrouped && ItemsView.ItemsSource is IEnumerable<IGrouping<string, object>> groups && platformView.Subviews[0] is UICollectionView collectionView)
{
// Enable index titles.
collectionView.DataSource = new GroupedCollectionViewDataSource(collectionView.DataSource, groups.Select(q => q.Key));
}
return platformView;
}
private class GroupedCollectionViewDataSource(IUICollectionViewDataSource datasource, IEnumerable<string> sections) : UICollectionViewDataSource
{
public override nint NumberOfSections(UICollectionView collectionView) => datasource.NumberOfSections(collectionView);
public override nint GetItemsCount(UICollectionView collectionView, nint section) => datasource.GetItemsCount(collectionView, section);
public override UICollectionViewCell GetCell(UICollectionView collectionView, NSIndexPath indexPath) => datasource.GetCell(collectionView, indexPath);
public override UICollectionReusableView GetViewForSupplementaryElement(UICollectionView collectionView, NSString elementKind, NSIndexPath indexPath) => datasource.GetViewForSupplementaryElement(collectionView, elementKind, indexPath);
public override string[] GetIndexTitles(UICollectionView collectionView) => sections.ToArray();
}
}
Note: This is available out-of-the-box on iOS 14 and above for a native UICollectionView. See documentation.
In the current CollectionView implementation, the CollectionView will start with all the groups expanded. The only way to have any form of preference is to programmatically interact with the DataView after-the-fact https://docs.telerik.com/devtools/maui/controls/collectionview/grouping/expand-collapse
Requested FeatureAdd an option to scroll fast to elements inside the CollectionView, something like jump list approach.
This feature is available in the iOS UICollectionView https://developer.apple.com/documentation/uikit/uicollectionviewdatasource/2851455-indextitlesforcollectionview
It could be a great addition to the Telerik MAUI RadCollectionView features set.
In MAUI CollectionView when scrolling an item into view, the exact position of the item after the scroll has completed can be specified with the position argument of the ScrollTo methods.
Please provide such option for Telerik MAUI CollectionView inside the ScrollItemIntoView method.
Currently the group descriptors provide a SortOrder property, so the groups are sorted alphabetically in descending or ascending order. We would need to cover the following scenarios:
- allow certain groups to be ordered at the top, possibly by specifying an comparer or a separate group sort property.
- show the groups in order the corresponding items appear in the ItemsSource.
Currently, the LoadOnDemandCollection accepts a callback of the following format in the constructor:
public LoadOnDemandCollection(Func<CancellationToken, IEnumerable> action)
It is a very common scenario to populate the items asynchronously. In its current form the collection would require blocking the current thread to populate the results:
ItemsSource = new LoadOnDemandCollection((cancelationToken) =>
{
var result = new List<ItemsModel>();
try
{
var items = dataService.GetItemsAsync().Result;
// TODO: Handle the result.
return result;
}
catch (Exception e)
{
// TODO: Handle the exception.
return null;
}
});
This is not desired, as using Task.Result blocks the current thread and is considered an anti-pattern, in general.
A better approach would be to add a second overload of the constructor, allowing asynchronous calls:
public LoadOnDemandCollection(Func<CancellationToken, Task<IEnumerable>> action)
This way we can use async and await in the callback instead:
ItemsSource = new LoadOnDemandCollection(async (cancelationToken) =>
{
var result = new List<ItemsModel>();
try
{
var items = await dataService.GetItemsAsync();
// TODO: Handle the result.
return result;
}
catch (Exception e)
{
// TODO: Handle the exception.
return null;
}
});
According to my tests, the first blocking approach is not a problem, as the LoadOnDemandCollection starts a thread internally. That behavior is not obvious however, and using Task.Result is somewhat counterintuitive, so the second approach is much better from the user's perspective.
The ItemsSource of the views is populated in the ViewModel of the page. This is done in a command that is triggered by the NavigatedTo event of the page, which is forwarded via EventToCommandBehavior from the Maui Toolkit.
When using the RadCollectionView the loaded items are no longer displayed.
When the ObservableCollection of the items is completely reconstructed and reassigned the display works.
we have additional field in City class (CountryFlag as Image)
public class City
{
public string Name { get; set; }
public string Country { get; set; }
public Image CountryFlag { get; set; }
}
We want to display the image instead of the property we group by. Provide such option to define which proeprty to be displayed in the group header.
See simple example baaaaif/CollectionViewFilterIssue (MainPage.xaml.cs) to reproduce, click hide and show
When items are filtered through a FilterDescriptor they are hidden - correct
Trying to show the previously hidden items they don't appear again as expected - bug
I've used a BooleanFilterDescriptor and a DelegateFilterDescriptor, both don't work.
Stops me from using the RadCollectionView control