testing
testing

Reputation: 20279

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?

Upvotes: 4

Views: 2716

Answers (1)

Sharada
Sharada

Reputation: 13601

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.

Upvotes: 12

Related Questions