Ended up with ICollectionView
and GroupStyle
. In addition to what I've here, I've these in OnApplyTemplate()
:
internalList = new TestList<Item>();
//internalList = new ObservableCollection<Item>();
internalView = CollectionViewSource.GetDefaultView(internalList);
internalView.GroupDescriptions.Add(new PropertyGroupDescription("Group"));
content.ItemsSource = internalView;
and in AddItem/RemoveItem
, instead of content.Items.Add/Remove
, I've to have internalList.Add/Remove
and one more method is necessary to refresh the internalView
when I'm done with a page:
public void RefreshInternalView() => internalView.Refresh();
a 114 page pdf report, with 3,600 entries in 4 groups takes 30-35 seconds to generate, not bad, right? I thought that instead of ObservableCollection<T>
, a subclass of IList<T>
, that implements INotifyCollectionChanged
, would reduce time BUT that's a joke I think! Spent a few hours on that and ended up with these:
public class TestList<T> : IList<T>, INotifyCollectionChanged
{
T[] _array = new T[50];
int itemCount = 0;
public void Add(T item)
{
_array[itemCount++] = item;
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, itemCount - 1));
}
public bool Remove(T item)
{
Array.Resize(ref _array, --itemCount);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, itemCount));
return true;
}
public IEnumerator<T> GetEnumerator()
{
for (int i = 0; i < itemCount; i++)
yield return _array[i];
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public event NotifyCollectionChangedEventHandler CollectionChanged;
void OnCollectionChanged(NotifyCollectionChangedEventArgs e) => CollectionChanged?.Invoke(this, e);
public T this[int index] { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public bool IsReadOnly => throw new NotImplementedException();
public int Count => throw new NotImplementedException();
public int IndexOf(T item) => throw new NotImplementedException();
public void Insert(int index, T item) => throw new NotImplementedException();
public void RemoveAt(int index) => throw new NotImplementedException();
public void Clear() => throw new NotImplementedException();
public bool Contains(T item) => throw new NotImplementedException();
public void CopyTo(T[] array, int arrayIndex) => throw new NotImplementedException();
}
the ObservableCollection<T>
beats it always by 1/2 second.