1

我正在构建一个自定义 VirtualizingPanel 以用于 ListBox 控件。我正在做一些测试,我在方法中遇到问题

IItemContainerGenerator.IndexFromGeneratorPosition(position) 

如果我在承载 ListBox 的 UserControl 的构造函数(在 Loaded 事件之前)中设置 ListBox 的 ItemsSource,它将返回 -1。但是,如果我要在 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();
    }
};

我应该如何以正确的方式解决这个问题?有什么建议么?

4

1 回答 1

0

IItemContainerGenerator.IndexFromGeneratorPosition如果没有为您的项目生成容器,将返回 -1。

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

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

ItemsOwner.ItemContainerGenerator.StatusChanged += (s, args) =>
{
    if (ItemsOwner.ItemContainerGenerator.Status == 
                       GeneratorStatus.ContainersGenerated)
    {
        // Your code goes here.         
    }
};
于 2013-09-15T20:12:41.670 回答