0

In ItemsControl I have placed my Collection of Items. As this collection can be very huge, I try to implement some paging - When scroll to the end of visible scroll area, add new items to ItemsControl.

Detecting of scroll bottom I've used from this answers How to find that ScrollViewer is scrolled to the end in WPF?

But I need to implement Adding of items.

if (scrollViewer.VerticalOffset == scrollViewer.ScrollableHeight &&
                _productsViewModel.ProductTotal > pageCount*ConfigurationProvider.ItemsPerProductPage)
            {
                pageCount++;
                _productsViewModel.RunPaginationWorker(pageCount);
            }

Items are added in BG Worker. As parameter I send pageNumber which is amount of times when user scroll to the end of scroll.

In BG CompleteWork event, I receive items and try to bind them to Property which is binded to ItemsControl

var items= (e.Result) as List<ItemDto>;
Items.AddRange(items);
OnPropertyChanged("Items");

But this doesn't work, it seems like Property Items isn't changed.


public List<ItemDto> Items
        {
            get { return _items; }
            set
            {
                _items= value;
                OnPropertyChanged("Items");
            }
        }

And Xaml Binding

<ItemsControl VerticalAlignment="Top" MaxWidth="650" HorizontalAlignment="Center" Margin="10,40,10,0" Name="Items" 
                          ItemsSource="{Binding Items}" AlternationCount="{Binding Path=Items.Count,FallbackValue='100'}">
...
</ItemsControl>
Community
  • 1
  • 1
demo
  • 6,038
  • 19
  • 75
  • 149
  • Normally you use an ObservableCollection as the type for Items. What are you using now? If you use an ObservableCollection, the event handling should be done implicitly without having to call any OnPropertyChanged. – Evert Feb 24 '16 at 11:36
  • Items is not an observable collection, is it? ObservableCollection doesn't have an AddRange method. – Valentin Feb 24 '16 at 11:37
  • If you have huge amount of items, you should use Binding. Here is an [example](http://stackoverflow.com/a/35577155/1560697) – NoName Feb 24 '16 at 11:41
  • @demo Can you show your binding? – Valentin Feb 24 '16 at 11:43
  • @Valentin, please check it in question now – demo Feb 24 '16 at 11:45
  • @demo Try to use `ObservableCollection`, instead of `List`. – Valentin Feb 24 '16 at 11:49

1 Answers1

0

You should use ObservableCollection<T> instead of List<T> as it implements the interfaces:

  • INotifyCollectionChanged
  • INotifyPropertyChanged

As such it is very useful when you want to know when the collection has changed. An event is triggered that will tell the user what entries have been added/removed or moved.

If you want to have method AddRange(), then just copy this code:

private ObservableCollection<ItemDto> _items=new ObservableCollection<ItemDto>();
public ObservableCollection<ItemDto> Items
{
    get { return _items; }
    set
    {
       _items= value;
       OnPropertyChanged("Items");
    }
}

public void AddRange(IEnumerable<T> collection)
{
    foreach (var i in collection)
    {
        Items.Add(i);
    }
}

Update:

If you want just take the last items, I would suggest you linq methods. For example, you can skip 10 items and take the next 10 items:

Items=Items.Skip(10).Take(10).ToList();

Update 1:

When you adding new items to collection and you do not want draw new items, then you should just add VirtualizingStackPanel.VirtualizationMode="Recycling". This will reduce the numbers of times to re-render new controls.

StepUp
  • 36,391
  • 15
  • 88
  • 148
  • But then I can't just add new items. I need to reinitialize `Items` with new Collection – demo Feb 24 '16 at 11:54
  • @demo Do you mean that when you add new items then you should create new collection? – StepUp Feb 24 '16 at 11:57
  • I just want to render new items in itemsControl. Old ones I just want to skip for better performance – demo Feb 24 '16 at 12:01
  • About Update - I want to render first 10 elements (as example) then, when scroll to the bottom, add new 10 elements etc. While do it, I don't want to re-render first 10 elements, just render new 10 elements. – demo Feb 24 '16 at 13:14
  • Or binder don't understand that I just add few items and there is no need to rebind old items? – demo Feb 24 '16 at 13:30
  • @demo feel free to ask any question. If my reply is helpful for you, then it is possible to assign my reply as answer to simplify the future search of other people. http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work – StepUp Feb 24 '16 at 14:55