Xamarin forms listview subclass vs listview with behavior

Viewed 28

I am trying to create a ListView subclass 'GeneralListView:ListView', so that I wouldn't have to specify a template and some other properties every time I use it. In the template I want to get object 'Order' from ItemsSource, but pass the converted object 'GeneralListViewItem' into the cell's Item property.

Definition of the ListView subclass called 'GeneralListView':

<ListView
  xmlns....
  RowHeight="70"
  SelectionMode="None">

  <ListView.Resources>
    <ResourceDictionary>
        <converters:GeneralListViewItemConvertor x:Key="ItemConvertor" />
    </ResourceDictionary>
  </ListView.Resources>

  <ListView.ItemTemplate>
    <DataTemplate>
         <controls:GeneralListViewViewCell Item="{Binding Path=., Converter={StaticResource ItemConvertor}, ConverterParameter={Binding ConvertorType}}"/>
    </DataTemplate>
  </ListView.ItemTemplate>
</ListView>

It being used in a ContentPage:

<controls:GeneralListView ItemsSource="{Binding Orders}" ConvertorType="Order" />

And the GeneralListViewViewCell template itself:

<ViewCell
  xmlns...>
  ...
  <FlexLayout Direction="Row" BindingContext="{Binding Source={RelativeSource AncestorType={x:Type ViewCell}}, Path=Item}">
    <Label Text="{Binding SomePropertyOfItem}" />
  </FlexLayout>
  ...
</ViewCell>

In the code behind, we can assume just the bindable properties. The problem is that in the cell I always get the original Order object, not the converted one. The converter is never triggered.

I ended up creating a listview behavior 'simulating' the Listview subclass and it works fine. I just don't understand why this didn't work... I'm pretty new to Xamarin, what am I misunderstanging here?..

My workaround with behavior:

public class GeneralListViewBehavior : Behavior<ListView>
{

    public BindableProperty ConvertorTypeProperty = BindableProperty.Create(nameof(ConvertorType), typeof(ConvertorTypeEnum), typeof(GeneralListViewBehavior));

    public ConvertorTypeEnum ConvertorType
    {
        ...
    }

    protected override void OnAttachedTo(ListView bindable)
    {
        base.OnAttachedTo(bindable);
        bindable.RowHeight = 70;
        bindable.SelectionMode = ListViewSelectionMode.None;

        DataTemplate template = new DataTemplate(typeof(GeneralListViewViewCell));
        Binding binding = new Binding(".", BindingMode.Default, new GeneralListViewItemConvertor(), ConvertorType);

        template.SetBinding(GeneralListViewViewCell.ItemProperty, binding);
        bindable.ItemTemplate = template;
    }
}

And finally it being used in a ContentPage:

<ListView ItemsSource="{Binding Orders}">
  <ListView.Behaviors>
    <behaviors:GeneralListViewBehavior ConvertorType="Order" />
  </ListView.Behaviors>
</ListView>
0 Answers
Related