Custom VirtualizingPanel:IItemContainerGenerator.IndexFromGeneratorPosition(position)返回-1

时间:2013-09-15 16:54:12

标签: c# wpf custom-controls virtualization custom-panel

我正在构建一个用于和ListBox控件的自定义VirtualizingPanel。 我正在做一些测试,我在方法中面临问题

IItemContainerGenerator.IndexFromGeneratorPosition(position) 

如果我在UserControl的构造函数(在Loaded事件之前)设置ListBox的ItemsSource,它将返回-1,它承载ListBox。但是,如果我在Loaded事件中设置ListBox的ItemsSource,它不会返回-1。

当我执行IItemContainerGenerator.Remove(position,offset)方法时发生NullReferenceException时出现问题。

下面的代码显示了虚拟化项目的方法

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);
        }

    }
}

目前我把这个(修复?hack?)放在我的VirtualizingPanel的构造函数

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

我应该如何正确解决这个问题?有什么建议吗?

1 个答案:

答案 0 :(得分:0)

IItemContainerGenerator.IndexFromGeneratorPosition将返回-1,以防生成您的商品的容器。

在构造函数时,您的项目不会在UI上呈现。因此,没有容器,但是在呈现UI后它们可用。这就是为什么你在加载事件后得到它们。

您可以在处理请求之前检查ItemContainerGenerator的状态,它应该是ContainersGenerated。挂钩到StatusChanged活动

ItemsOwner.ItemContainerGenerator.StatusChanged += (s, args) =>
{
    if (ItemsOwner.ItemContainerGenerator.Status == 
                       GeneratorStatus.ContainersGenerated)
    {
        // Your code goes here.         
    }
};