How to split UIElement and add pieces in several FixedPage

Emon Haque 3,176 Reputation points
2020-10-11T12:53:24.357+00:00

For example, with this:

var grid = new Grid() { Children = { listBox} };
grid.Measure(new Size(page.Width, double.PositiveInfinity));
grid.Arrange(new Rect(grid.DesiredSize));

I see that the listBox needs to span several pages and with grid.DesiredSize.Height / page.Height, I know that it need 3 pages. How can I split the grid/listBox and access each segments to add into pages?

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,691 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Emon Haque 3,176 Reputation points
    2020-10-12T00:11:57.96+00:00

    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.

    0 comments No comments