【问题标题】:What's the proper way to set CachingStrategy to RecycleElement in Xamarin Forms?在 Xamarin 表单中将 CachingStrategy 设置为 RecycleElement 的正确方法是什么?
【发布时间】:2020-02-18 17:11:37
【问题描述】:

我遇到了一个错误(但我的代码仍在运行,所以直到现在我一直忽略它)说我的 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.

我猜这是导致我再次崩溃的原因:System.ObjectDisposedException: Cannot access a disposed object. Object name: 'Xamarin.Forms.Platform.Android.FormsTextView' 因为我在网上看到建议说大部分时间这个问题都和ListView有关,应该把CachingStrategy设置为RecycleElement。

所以我决定最后看一下 BindableListView 并添加CachingStrategy = "RecycleElement"

现在已经实现了一些似乎已经尝试添加 CachingStrategy 的代码:

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;
    ...

然后在所有使用此 ListView 的 .xaml 文件中:

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

这是将 CachingStrategy 设置为 Recycle Element 的正确方法吗?如果是这样,那么我将如何解决我的错误?

或者我应该从 BindableListView.cs 中的构造函数中删除参数以使其无参数,然后只添加一行 CachingStrategy = "RecycleElement" ?我试过这个,至少错误消失了..(虽然应用程序现在无法运行,“缺少默认 ctor”)但我不知道这是否是正确的做法。如果这是我应该做的,这也会解决我的第二个错误吗?

谢谢!

【问题讨论】:

    标签: c# android xaml xamarin.forms


    【解决方案1】:

    适用于您的情况的错误消息部分是:

    ...没有定义公共无参数构造函数...

    改变这个:

    public BindableListView(ListViewCachingStrategy cachingStrategy)
                : base(cachingStrategy)
    {
        ItemTapped += OnItemTapped;
        ItemAppearing += OnItemAppearing;
        ItemSelected += OnItemSelected;
        ...
    }
    

    到这里:

    public BindableListView(ListViewCachingStrategy cachingStrategy)
            : base(cachingStrategy)
    {
        Init();
    }
    
    public BindableListView()
            : base()
    {
        Init();
    }
    
    private void Init()
    {
        ItemTapped += OnItemTapped;
        ItemAppearing += OnItemAppearing;
        ItemSelected += OnItemSelected;
        ...
    }
    

    请注意,您确实希望保留参数化构造函数(XAML 需要它);所以解决方案是添加一个 second(无参数)构造函数。

    因此,您将拥有所需的两种形式的构造函数,并且它们中的每一种都将执行您的初始化逻辑。

    【讨论】:

      【解决方案2】:

      从您的代码来看,我认为将 CachingStrategy 设置为 Recycle Element 是正确的方法。

      根据本文档:

      https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/listview/performance

      解决这个问题的方法是在子类 ListView 上指定一个构造函数,该构造函数接受 ListViewCachingStrategy 参数并将其传递给基类:

      public class CustomListView : ListView
      {
      
         public CustomListView (ListViewCachingStrategy strategy) : base (strategy)
          {
      
          }
          ...
      }
      

      然后可以使用 x:Arguments 语法从 XAML 中指定 ListViewCachingStrategy 枚举值

      <local:CustomListView>
      <x:Arguments>
          <ListViewCachingStrategy>RecycleElement</ListViewCachingStrategy>
      </x:Arguments>
      

      【讨论】:

        猜你喜欢
        • 2017-06-25
        • 2012-02-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-08
        • 2013-09-06
        • 2023-03-23
        • 2017-12-17
        相关资源
        最近更新 更多