【问题标题】:Xamarin bug-ish behaviour in CarouselView - CurrentItemChanged event fired unexpectedly?CarouselView 中的 Xamarin 错误行为 - CurrentItemChanged 事件意外触发?
【发布时间】:2021-03-14 08:02:20
【问题描述】:

在尝试实现无限滚动页面时,我遇到了 Xamarin.Forms.CarouselViewCurrentItemChanged 事件的奇怪行为。

当用户滚动时,新项目被添加到ItemSource,旧项目被删除(为了减少内存消耗)。

在遇到奇怪的行为后,我已经调试并缩小了问题范围。

所以这里是复制这种情况的步骤。

  • 创建CarouselView
  • 在后面的代码中创建一个ObservableCollection<T>,并将其分配给ItemSource
  • 创建一个方法并将其订阅到CarouselViewCurrentItemChanged 事件。此方法必须在某个时候从ItemSource 中删除一个索引在0CurrentItem 的索引之间的元素。
  • 现在部署应用程序并滑动CarouselView 一次。这将导致无限循环的滚动,直到所有项目都从 ItemSource 中删除。

步骤 3 中的方法必须如下所示。

bool FirstTime = true;
private void StateChanged(object s, EventArgs e)
{
    // Pass the first call which is made right after the Carousel is initialized.
    if (FirstTime) { FirstTime = false; return; }

    var currentItem = (Model)Carousel.CurrentItem; // For debug.
    var index = Models.IndexOf(currentItem); // Same.

    // Step 3's requirement
    Models.RemoveAt(0);
}

例如,当您向页面添加一个按钮并将您在第 3 步中创建的方法分配给它的 Clicked 事件,然后继续第 4 步并在每次滚动后手动按下按钮时,无限循环获胜'不会发生。


我不知道这是一个功能还是一个错误,但这肯定是出乎意料的,至少对我来说是这样。我很想弄清楚如何克服这个问题并了解它为什么会这样。

注意:我知道删除当前项目会导致此类问题,但所描述的行为会以任何一种方式发生。此外,CarouselView.CurrentItem 会在 CurrentItemChanged 事件触发之前更新。

【问题讨论】:

    标签: c# xamarin model-view-controller xamarin.forms mvvm


    【解决方案1】:

    这将导致无限循环的滚动,直到所有项目都从 ItemSource 中删除。

    这是因为ObservableCollection 具有 CollectionChanged 事件,该事件将在数据收集更改时调用。当您删除第一项时,索引被引用并且事件也将被触发。

    对于此功能,您可以检测当前项目是否是最后一个更新数据集合的项目。检查代码:

    public partial class Page1 : ContentPage
    {
        CustomViewModel viewModel = new CustomViewModel();
        ObservableCollection<CustomModel> collection;
        public Page1()
        {
            InitializeComponent();
    
            BindingContext = viewModel;
            collection = viewmodel.DataCollection;
        }
    
        private void CarouselView_CurrentItemChanged(object sender, CurrentItemChangedEventArgs e)
        {
            var item = e.CurrentItem as CustomModel;
            var index = collection.IndexOf(item);
    
            if (collection.Count == (index + 1))
            {
                collection.RemoveAt(0);
                collection.Add(new CustomModel { ... });
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-26
      相关资源
      最近更新 更多