1

I am building a custom VirtualizingPanel to be used in and ListBox control. I am doing some testing where i faced a problem in the method

IItemContainerGenerator.IndexFromGeneratorPosition(position) 

It returns -1 if I set the ListBox's ItemsSource in the constructor(which is before the Loaded event) of my UserControl where it hosts the ListBox. However, it does not returns -1 if I were to set the ListBox's ItemsSource in the Loaded event.

The problem arises when a NullReferenceException occurs when i execute the IItemContainerGenerator.Remove(position, offset) method.

The code below shows the method where i virtualize the items

private void CleanupItems()
{
    IItemContainerGenerator iGenerator = this.ItemsOwner.ItemContainerGenerator;

    for (int i = this.InternalChildren.Count - 1; i >= 0; i--)
    {

        GeneratorPosition position = new GeneratorPosition(i, 0);
        int itemIndex = iGenerator.IndexFromGeneratorPosition(position);

        if (itemIndex < this.StartIndex || itemIndex > this.EndIndex)
        {
            iGenerator.Remove(position, 1);
            this.RemoveInternalChildRange(i, 1);
        }

    }
}

currently i put this(fix?hack?) in my VirtualizingPanel's constructor

Loaded += (s, e) =>
{
    if (ItemsOwner.ItemsSource != null)
    {
        this.InvalidateMeasure();
    }
};

how should i fix this issue the correct way? any suggestions?

Marc
  • 3,905
  • 4
  • 21
  • 37
icube
  • 2,578
  • 1
  • 30
  • 63

1 Answers1

0

IItemContainerGenerator.IndexFromGeneratorPosition will return -1 in case containers for your items are not generated.

At the time of constructor your items are not rendered on UI. Hence no containers but they are available once your UI is rendered. That's why you are getting them after loaded event.

You can check Status of your ItemContainerGenerator, it should be ContainersGenerated before processing your request. Hook to StatusChanged event

ItemsOwner.ItemContainerGenerator.StatusChanged += (s, args) =>
{
    if (ItemsOwner.ItemContainerGenerator.Status == 
                       GeneratorStatus.ContainersGenerated)
    {
        // Your code goes here.         
    }
};
Rohit Vats
  • 79,502
  • 12
  • 161
  • 185
  • thanks for the reply, would you mind explaining the lifecycle of the ItemContainerGenerator? – icube Sep 16 '13 at 15:04
  • Link here - http://drwpf.com/blog/category/item-containers/ will help you understand that how it works. – Rohit Vats Sep 16 '13 at 18:26
  • Hi, Im still facing this problem. Actually the status of the ItemContainerGenerator is already ContainersGenerated when i execute my above CleanUpItems() method... so i think your reply is not valid – icube Oct 21 '13 at 04:56