How to create a custom template for ViewCell composed of 2 template

NicolasKrierNicolasKrier FRMember ✭✭✭
edited November 2018 in Xamarin.Forms

Hello,

I use a dozen of ListView (SfListView from SyncFusion) in my application.

Here is the kind of template I use :

My ListViewItem contains a button that set the ListViewItem with an IsSelected property.

When a cell is selected, I display a list of command to navigate to other pages.

I'm looking for a way to extend the ListView to expose 2 Bindable Property of type ControlTemplate because all my ListView as a "menu" button on the right and I wanted to factorize some logic used to force the layout update of the selected cell.

I want to have 2 ControlTemplate. 1 for the traditionnal ItemTemplate and 1 for the list of available menu actions.

I've been struggling all day long trying to make it work but it's harder to customize with XForms' XAML than traditionnal XAML.

Did anyone achieve something similar ? Should I extend ViewCell and expose some control template and other bindable properties inside or is it enough to expose them in the ListViewExtended and use those BP inside a control template with TemplateBinding ?

Any help/thought on this will be very appreciated.

The only workaround I found to work is to dupplicate all the code or having a BaseListPageViewModel but that's far from the best solution IMHO. (and I can't factorize the XAML, only the code exectuted by the ListView)

Have a good day and thanks for your time if you read my problem so far :)

Answers

  • LandLuLandLu Member, Xamarin Team Xamurai

    I think DataTemplateSelector could be something you want.
    Firstly create your own custom data template selector:

    public class CustomDataTemplateSelector : DataTemplateSelector
    {
        public DataTemplate SelectedTemplate { get; set; }
        public DataTemplate UnSelectedTemplate { get; set; }
        protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
        {
            return ((Model)item).IsSelected ? SelectedTemplate : UnSelectedTemplate;
        }
    }
    

    Then define these two different templates in your content page's resources:

    <ContentPage.Resources>
        <ResourceDictionary>
            <DataTemplate x:Key="selectedTemplate">
                <ViewCell>
                    ...
                </ViewCell>
            </DataTemplate>
            <DataTemplate x:Key="unselectedTemplate">
                <ViewCell>
                    ...
                </ViewCell>
            </DataTemplate>
            <local:CustomDataTemplateSelector x:Key="myDataTemplateSelector"
            SelectedTemplate="{StaticResource selectedTemplate}"
            UnSelectedTemplate="{StaticResource unselectedTemplate}" />
        </ResourceDictionary>
    </ContentPage.Resources>
    

    At last consume this template selector in your list view like:

    <ListView x:Name="listView" ItemTemplate="{StaticResource myDataTemplateSelector}" />

  • NicolasKrierNicolasKrier FRMember ✭✭✭
    edited November 2018

    Hello, thanks a lot . I should have stated that TemplateSelector isn't something I want to use.
    The main reason is that my items are not selectable (SelectionMode=none).

    When users click on an item it operates a simple navigation. When users click on the menu button, a additionnal panel is added (IsVisible=true). I tried the TemplateSelector but due to several limitations : the height of the item isn't updated on iOS (a bug well known), an option is to force the layout but most of the times every single item displayed or at least, the selected item one flicker hard when the template switch from NormalTemplate to SelectedTemplate. Sometimes the whole listview render again. It's a bad user experience.

    With my way of doing, it feels way better.
    Eventhought I put aside the TemplateSelector, it doesn't mean that it wasn't my first intention. I prefer this approach but it doesn't work that great so I had to find other way.

    Thank you for your time, I appreciate.

Sign In or Register to comment.