2017-02-13 11 views
0

Я разрабатываю приложение, которое используется для работы с 20k + элементами, отображаемыми в списке WPF, поэтому очевидно, что их нужно разделить на страницы.Пейджинг с CreateDerivedCollection

Мое текущее решение немного лага:

я применить фильтр с помощью команды асинхронной с Paraller.ForEach по всем пунктам, и я установить MatchesFilter собственность. Это прекрасно работает:

FilteredItems = _allItems.CreateDerivedCollection(x => x, x 
=> x.MatchesFilter, scheduler: RxApp.TaskpoolScheduler); 

_count =FilteredSignatures.CountChanged.StartWith(0).ToProperty(this, x => x.Count); 

Это быстро, сохраняет пользовательский интерфейс отзывчивый и вы можете видеть граф быстро меняется в WPF Label.

При фильтрации концов, я делаю (на основном потоке):

Items.Clear(); 
foreach (var s in FilteredItems.Skip((CurrentPage - 1) * temsPerPage).Take(ItemsPerPage)) 
         Items.Add(s); 

И это где моя проблема. Каждый элемент отображается вместе с изображением, которое загружается async из URL-адреса. Элемент Clear() незаметно замораживает пользовательский интерфейс. У меня 250 элементов на странице (это не должно быть меньше, потому что пользователь должен иметь возможность искать элемент на основе изображения своим глазом).

Есть ли лучший способ сделать это? Я знаю о DynamicData, но использует RxUI 6.x.

ответ

2

Вы можете использовать DynamicData с RxUI 7,0

+0

Я получаю сообщение об ошибке Reactive.Interfaces 2.5.5. Какую версию я должен использовать? –

+0

Последняя версия на 4.x, поскольку она основана на Rx 2.x. https://www.nuget.org/packages/DynamicData/4.10.1.1194 – Erlend

+0

Спасибо. Просто из любопытства, можно ли достичь чистого RxUI? –

0

Dynamic Data 4 отлично работает с RxUI 6,5, и это то, что я использую в целом. Это, как говорится, я хотел просто разместить образец кода для этого с помощью RxUI. В основном потому, что вам не нужно очищать, а затем повторно добавлять, чтобы обновить DerivedList.

[TestMethod] 
    [TestCategory("Reactive")] 
    public async Task PagingReactiveUITest() 
    { 

     ReactiveList<int> SourceList = new ReactiveList<int>(); 
     for (int i = 0; i < 100; i++) 
     { 
      SourceList.Add(i); 
     } 

     Tuple<int, int> pageWindow = new Tuple<int, int>(0, 10); 


     //ReactiveComamnd that triggers paging 
     ReactiveCommand<Unit> updatePaging = 
      ReactiveCommand.CreateAsyncObservable<Unit>((_) => 
      { 

       pageWindow = new Tuple<int, int>(10, 20); 
       return Observable.Return(Unit.Default); 
      }); 


     var PagedList = 
      SourceList 
      .CreateDerivedCollection(
       x => x, 
       filter: (item) => item >= pageWindow.Item1 && item < pageWindow.Item2, 
       signalReset: updatePaging); 



     Assert.AreEqual(PagedList.First(), 0); 
     Assert.AreEqual(PagedList.Last(), 9); 

     //Trigger Paging 
     await updatePaging.ExecuteAsync(null); 

     Assert.AreEqual(PagedList.First(), 10); 
     Assert.AreEqual(PagedList.Last(), 19); 
    } 

Еще одно замечание .. Если вы планируете делать много изменений в списке вы также можете сделать что-то вроде

using (SourceList.SuppressChangeNotifications()) 
{ 
     //DO STUFF 
} 

который остановит сообщения от перехода к пользовательскому интерфейсу, пока вы не закончите возиться со списком

+0

Ваше решение было бы здорово, если бы функция преобразования (или фильтра) выглядела как (x, i) => новый Tuple (i, x). Тогда да, но, к сожалению, это не так. –

+0

Ну фильтр и кортеж могут быть чем-то действительно. Это был всего лишь надуманный пример, чтобы показать вам некоторые дополнительные функции, не снимая и не заполняя список. Вы можете проверить для IndexOf элемент в функции фильтра, чтобы узнать, находится ли он между вашими требованиями к пейджинговой связи. SuppressChangeNotifications может также быть полезен, если не «заморозить» пользовательский интерфейс ... Это говорит о том, что если ваш исходный список довольно велик, я не думаю, что в RxUI есть что-то, что будет эффективно обновлять производный список супер по сравнению с DyamicData. –

+0

Да, я только что проверил образец 20k и даже с DynamicData - это способ замедлить работу. Теперь я выполняю ручную фильтрацию и внутреннюю команду с помощью PLINQ, а затем заполняя список конечных элементов. Я также использовал SuppressChangeNotifications и пользовательский интерфейс зависает в течение более короткого времени, но он по-прежнему примечателен. По крайней мере, сейчас, когда я меняю страницы или что-то пишу в окне фильтра, это можно использовать. Спасибо за понимание –