Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using CachingStrategy on ListViewRenderer causes property error

I have a view with a ListView on it. Now I switched to a custom renderer for this ListView (and a custom renderer for the ViewCell btw). If I start the app in the simulator (iOS, Android) I get the following exception:

Xamarin.Forms.Xaml.XamlParseException: Position 12:13. Cannot assign property "CachingStrategy": Property does not exists, or is not assignable, or mismatching type between value and property

If I remove the CachingStrategy everything seems to work fine. Here is my code:

View, where the ListView is placed on:

<StackLayout xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MyApp.Views.SomeView"
             xmlns:customViews="clr-namespace:MyApp.Views;assembly=MyApp"
             xmlns:renderer="clr-namespace:MyApp.CustomRenderers;assembly=MyApp"
             VerticalOptions="FillAndExpand">

  <renderer:CustomListView x:Name="SomeList"
            SeparatorColor="{StaticResource PrimaryLight}"
            HasUnevenRows="True"
            CachingStrategy="RecycleElement"
            IsGroupingEnabled="True" 
            GroupDisplayBinding="{Binding Key}"
            IsPullToRefreshEnabled="True"
            RefreshCommand="{Binding LoadDocumentsCommand}"
            IsRefreshing="{Binding IsBusy, Mode=OneWay}">
    <ListView.GroupHeaderTemplate>
      <DataTemplate>
        <customViews:GroupingHeader/>
      </DataTemplate>
    </ListView.GroupHeaderTemplate>

    <ListView.ItemTemplate>
      <DataTemplate>
        <customViews:MyListItem Clicked="Item_Clicked"/>
      </DataTemplate>
    </ListView.ItemTemplate>
  </renderer:CustomListView>

</StackLayout>

CustomListView

namespace MyApp.CustomRenderers
{
    public class CustomListView : ListView
    {
    }
}

CustomListViewRenderer

[assembly: ExportRenderer(typeof(MyApp.CustomRenderers.CustomListView), typeof(MyApp.iOS.CustomRenderers.CustomListViewRenderer))]
namespace MyApp.iOS.CustomRenderers
{
    public class CustomListViewRenderer : ListViewRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
        {
            base.OnElementChanged(e);

            if (this.Control != null)
            {
                var listView = (UITableView)this.Control;
                if (listView != null)
                {
                    listView.SeparatorInset = UIEdgeInsets.Zero;
                }
            }
        }
    }
}

Should I replicate the property or do I need a different constructor?

like image 755
testing Avatar asked Sep 15 '25 11:09

testing


1 Answers

You are getting this error because CachingStrategy is not a bindable property but a constructor argument that is supplied by XAML parser or build task.

OPTION-1

To get around this, you can change the constructor to accept CachingStrategy:

public class CustomListView : ListView
{
    public CustomListView(ListViewCachingStrategy cachingStrategy) : 
                base(cachingStrategy)
    {

    }
}

And, change your XAML to specify caching-strategy as constructor argument:

<renderer:CustomListView x:Name="SomeList"
            HasUnevenRows="True"
            IsGroupingEnabled="True" 
            GroupDisplayBinding="{Binding Key}"
            IsPullToRefreshEnabled="True"
            RefreshCommand="{Binding LoadDocumentsCommand}"
            IsRefreshing="{Binding IsBusy, Mode=OneWay}">
    <x:Arguments>
        <ListViewCachingStrategy>RecycleElement</ListViewCachingStrategy>
    </x:Arguments>
    <ListView.GroupHeaderTemplate>
      <DataTemplate>

OPTION-2

There is a hack available where you can create your own parameter attribute. But it only works when XAML compilation is ON. More details here.

like image 84
Sharada Gururaj Avatar answered Sep 17 '25 02:09

Sharada Gururaj