Skip to content

Enhancing collection's items

Nikita edited this page Jan 28, 2022 · 11 revisions

Introduction

You will definitely have interactable array of items. A typical example would be list with navigable items, in which, clicking on a particular item leads to the details page with this specific item's information.

However, you don't have direct access to each item's context in the collection (items are created and handled by the collection control itself with the help of a DataTemplate), thus you cannot apply desired attributes on it. Moreover, sometimes you need to pass your parent's binding context down to each item. This library provides solution to this situation on a DataTemplate level. A new HostedDataTemplate option helps you to populate each item on a convenient manner.

HostedDataTemplate

This is the derival of existing Xamarin.Forms.DataTemplate component. Currently it adds new following functionality:

  • Ability to populate each item with attached asynchronous commands, if any assigned (task should be provided from the parent binding context)
  • Ability to populate each item with asynchronous commands, if any assigned (task should be provided from the parent binding context)
  • Ability to populate each item with attached commands, if any assigned (method delegate should be provided from the parent binding context)
  • Ability to populate each item with classic commands, if any assigned (method delegate should be provided from the parent binding context)

A dedicated item's class is required. You should put desired attributes inside of it and consume as following:

<!--MyPage.xaml-->
<ContentPage x:Class="Your.Namespace.MyPage" x:Name="myPage" ...>
    <CollectionView ...>
        <!--...-->
        <CollectionView.ItemTemplate>
            <dataTemplates:HostedDataTemplate>
                <x:Arguments>
                    <wrappers:TypeWrapper Type="{x:Type items:SpecificCollectionItem}"
                        Parent="{x:Reference myPage}"/>
                </x:Arguments>
            </dataTemplates:HostedDataTemplate>
        </CollectionView.ItemTemplate>
        <!--...-->
    <CollectionView>
</ContentPage>

You should provide your item's type as Type property and your current page link as Parent property for TypeWrapper instance.

// SpecificCollectionItem.xaml.cs
[AttachedAsyncCommand(
    commandTaskName: nameof(AnyViewModel.AnythingAsync))]
public partial class SpecificCollectionItem : ContentView //May also derive from Grid, StackLayout, etc.
{
    public SpecificCollectionItem() =>
        InitializeComponent();
}
<!--SpecificCollectionItem.xaml-->
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Your.Namespace.SpecificCollectionItem"
             x:Name="specificCollectionItem">
    <!--Body-->
</ContentView>