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>