3

Я был создан ListView, который имеет бесконечную прокрутку с помощью ObservableRangeCollection. Он отлично работает на Android, но на iOS он запускается, когда он добавляет новые элементы. Paginating выполняется с поведением. ListView - это FlowListView. Вот XAML:Бесконечный ListView на iOS после обновления переходов к первому элементу

... 
FlowItemsSource="{Binding Profiles.Result} 
... 
<controls:FlowListView.Behaviors> 
     <behaviors:FlowListViewPaginating 
      Command="{Binding LoadMoreCommand}" 
      Converter="{StaticResource ItemVisibilityConverter}"> 
     </behaviors:FlowListViewPaginating> 
     </controls:FlowListView.Behaviors> 
... 

Поведение:

public class FlowListViewPaginating : Behavior<FlowListView> 
    { 
     public FlowListView AssosiatedObject { get; private set; } 

     public static readonly BindableProperty CommandProperty = 
      BindableProperty.Create("Command", typeof(DelegateCommand<Profile>), typeof(FlowListViewPaginating), null); 

     public static readonly BindableProperty InputConverterProperty = 
      BindableProperty.Create("Converter", typeof(IValueConverter), typeof(FlowListViewPaginating), null); 


     public DelegateCommand<Profile> Command 
     { 
      get { return (DelegateCommand<Profile>)GetValue(CommandProperty); } 
      set { SetValue(CommandProperty, value); } 
     } 

     public IValueConverter Converter 
     { 
      get { return (IValueConverter)GetValue(InputConverterProperty); } 
      set { SetValue(InputConverterProperty, value); } 
     } 

     protected override void OnAttachedTo(FlowListView bindable) 
     { 
      base.OnAttachedTo(bindable); 

      AssosiatedObject = bindable; 
      bindable.BindingContextChanged += OnBindingContextChanged; 
      bindable.ItemAppearing += OnItemAppearing; 
     } 

     protected override void OnDetachingFrom(FlowListView bindable) 
     { 
      base.OnDetachingFrom(bindable); 

      bindable.BindingContextChanged -= OnBindingContextChanged; 
      bindable.ItemAppearing -= OnItemAppearing; 
      AssosiatedObject = null; 
     } 

     private void OnItemAppearing(object sender, ItemVisibilityEventArgs e) 
     { 
      var flowListView = (FlowListView)sender; 

      if (flowListView.IsRefreshing) return; 
      if (Command == null) return; 

      var parameter = Converter.Convert(e, typeof(object), null, null) as Profile; 
      if (Command.CanExecute(parameter)) 
       Command.Execute(parameter); 
     } 

     protected void OnBindingContextChanged(object sender, EventArgs e) 
     { 
      OnBindingContextChanged(); 
     } 

     protected override void OnBindingContextChanged() 
     { 
      base.OnBindingContextChanged(); 

      BindingContext = AssosiatedObject.BindingContext; 
     } 


    } 

конвертер для поведения:

public class ItemVisibilityEventConverter : IValueConverter 
    { 
     public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      var eventArgs = value as ItemVisibilityEventArgs; 
      var collection = eventArgs?.Item as System.Collections.ObjectModel.ObservableCollection<object>; 
      return collection[0]; 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      throw new NotImplementedException(); 
     } 
    } 

Моя коллекция:

public NotifyTask<ObservableRangeCollection<Profile>> Profiles { get; set; } 

NotifyTask имеет nothi ng делать с коллекцией. Это просто обертка.

метод, где я добавлять элементы:

private async Task OnLoadMore(Profile lastProfile) 
     { 
      IsBusy = true; 
      _pageNumber++; 
      Profiles.Result.AddRange(await _manager.GetProfilesAsync(_parameters.NextPage())); 
      IsBusy = false; 
     } 
+0

Что такое 'FlowListView'? Это не часть Xamarin.Forms – Krumelur

+0

@Krumelur Вот он: https://github.com/daniel-luberda/DLToolkit.Forms.Controls/tree/master/FlowListView –

+0

Вам стоит подумать над тем, чтобы поднимать проблему. https://github.com/daniel-luberda/DLToolkit.Forms.Controls/issues – Krumelur

ответ

2

Эти примеры не будут прокручивать список на прошивкой/Android, когда элементы обновляются. Обязательно используйте новейший пакет nuget.

XAML:

<flv:FlowListView FlowColumnCount="3" SeparatorVisibility="None" HasUnevenRows="false" 
    FlowItemTappedCommand="{Binding ItemTappedCommand}" FlowLastTappedItem="{Binding LastTappedItem}" 
    FlowItemsSource="{Binding Items}" Grid.ColumnSpan="2"> 

    <flv:FlowListView.FlowColumnTemplate> 
     <DataTemplate> 
      <Label HorizontalOptions="Fill" VerticalOptions="Fill" 
       XAlign="Center" YAlign="Center" Text="{Binding Title}"/> 
     </DataTemplate> 
    </flv:FlowListView.FlowColumnTemplate> 

</flv:FlowListView> 

Вид модели:

public UpdateItemsPageModel() 
{ 
    AddCommand = new BaseCommand((arg) => 
    { 
     insertId++; 
     Items.Insert(10, new SimpleItem() { Title = string.Format("New {0}", insertId) }); 
    }); 

    RemoveCommand = new BaseCommand((arg) => 
    { 
     Items.RemoveAt(10); 
    }); 
} 

public ObservableCollection<object> Items 
{ 
    get { return GetField<ObservableCollection<object>>(); } 
    set { SetField(value); } 
} 
+1

Я обновил список listview nuget до последнего стабильного, заменил события, как вы сказали, и попытался добавить элементы со вставкой. И есть мое наблюдение: - если я добавлю один элемент, как в вашем примере, то он работает, но если этот элемент не загружается, он сбой с этой ошибкой: MonoTouch.Foundation.MonoTouchException: исключение Objective-C. Имя: NSRangeException Причина: *** - [__ NSArrayM objectAtIndex:]: Если я добавляю элементы в цикл со вставкой или добавлением или addRange, то будет таким же, как и раньше. –

+0

Но я заметил, что если точно до следующей страницы у меня есть палец на дисплее (эмулятор), тогда он работает. Он не обновляет индикатор и просто добавляет элементы в тишину. Но когда есть индикатор, он переходит на первую страницу. На Android все работает как шарм. С индикатором, без переходов и с любым кодом. –

+0

Не могли бы вы сделать репродукцию и отправить ее мне? Моя электронная почта находится на моей странице учетной записи github. Я попытаюсь исправить это, если это ошибка :) –

0

Я нашел обходной путь в моей ситуации. Вот код, когда он отлично работает:

private void OnLoadMore(Profile lastProfile) 
     { 
      IsBusy = true; 
      _pageNumber++; 

      Device.BeginInvokeOnMainThread(async() => 
      { 
       var newItems = await _manager.GetProfilesAsync(_parameters.NextPage()); 
       Profiles.Result.AddRange(newItems); 
      }); 

      IsBusy = false; 
     } 

Есть еще одна проблема. Он не показывает индикатор загрузки. На iOS и Android. Если я поместил остаток кода метода в основной поток или переместил GetProfilesAsync из основного потока, он будет прыгать, как раньше.

Смежные вопросы