Forum Xamarin.Forms

What's the best way to let CachingStrategy = RecycleElement for XAML?

chunggchungg Member ✭✭

I've been getting an error (but my code still runs with it so I've been ignoring it until now) saying that my BindableListView is not usable as an object element because it is not public or does not define a public parameterless constructor or a type converter.

I'm guessing this is the cause of another crash I'm getting: System.ObjectDisposedException: Cannot access a disposed object. Object name: 'Xamarin.Forms.Platform.Android.FormsTextView'
because I've seen suggestions online saying that most of the time, this issue is related to the ListView, and that I should set the CachingStrategy to RecycleElement.

So I decided to finally take a look at the BindableListView and add in the CachingStrategy = "RecycleElement"

Now there was already some code implemented that seemed to try and add the CachingStrategy already:

BindableListView.cs:

namespace MyApp.Core.Controls
{
    [PropertyChanged.DoNotNotify]
    public class BindableListView : ListView
    {
        public static BindableProperty ItemClickedProperty = BindableProperty.Create(nameof(ItemClicked), typeof(ICommand), typeof(BindableListView));
        public static BindableProperty ItemAppearsProperty = BindableProperty.Create(nameof(ItemAppears), typeof(ICommand), typeof(BindableListView));
        public static BindableProperty AnimateScrollToSelectedItemProperty = BindableProperty.Create(nameof(AnimateScrollToSelectedItem), typeof(bool), typeof(BindableListView), true);

        /// <summary>
        /// Constructs a <see cref="BindableListView"/>
        /// </summary>
        /// <param name="cachingStrategy">Sets the caching strategy for the <see cref="ListView"/>.</param>
        /// <example><![CDATA[
        /// <controls:BindableListView>
        ///  <x:Arguments>
        ///    <ListViewCachingStrategy>RecycleElement</ListViewCachingStrategy>
        ///  </x:Arguments>
        /// </controls:BindableListView>
        /// ]]></example>
        public BindableListView(ListViewCachingStrategy cachingStrategy)
            : base(cachingStrategy)
        {
            ItemTapped += OnItemTapped;
            ItemAppearing += OnItemAppearing;
            ItemSelected += OnItemSelected;
    ...

Then in all the .xaml files that use this ListView:

<controls:BindableListView
      ...>
      <x:Arguments>
        <ListViewCachingStrategy>RecycleElement</ListViewCachingStrategy>
      </x:Arguments>

Would this be the correct way to set CachingStrategy to Recycle Element? If so then how would I go about fixing my error(s)?

Or should I remove the parameter from the constructor in BindableListView.cs to make it parameterless, and then just add the one line CachingStrategy = "RecycleElement" ? I tried this and I got "missing default ctor". I don't know if it's the right idea though? If this is what I'm supposed to do, will this fix my second error as well?

Thanks!

Answers

  • ColeXColeX Member, Xamarin Team Xamurai

    Would this be the correct way to set CachingStrategy to Recycle Element?

    The solution to this issue is to specify a constructor on the subclassed ListView that accepts a ListViewCachingStrategy parameter and passes it into the base class:

    Your code is correct , check official documentaiton : Set the caching strategy in a subclassed ListView .

  • chunggchungg Member ✭✭

    Then how come I'm getting the first error that I posted? @ColeX

    And how can I change it to fix the crash our clients are getting?

  • AdamMeaneyAdamMeaney USMember ✭✭✭✭✭

    I would say you are close here to just making them all be recycle.

    I would just change it to

    public BindableListView()
                : base(ListViewCachingStrategy.RecycleElement)
            {
                ItemTapped += OnItemTapped;
                ItemAppearing += OnItemAppearing;
                ItemSelected += OnItemSelected;
    
  • DirkWilhelmDirkWilhelm USMember ✭✭✭✭

    As the error message says, you need an additional parameterless ctor.

    public BindableListView() : base()
    {
    
    }
    

    So in the end you will have two ctor in your BindableListView.cs

Sign In or Register to comment.