Wpf .Net 4.0中VirtualzingStackPanel.CacheSize的替代方案 当StukPad决定可视项目周围的可视化项目时,虚拟化的因素是什么?

Wpf .Net 4.0中VirtualzingStackPanel.CacheSize的替代方案 当StukPad决定可视项目周围的可视化项目时,虚拟化的因素是什么?,wpf,listview,scrollviewer,virtualizingstackpanel,Wpf,Listview,Scrollviewer,Virtualizingstackpanel,例如:有一个列表视图,当查看第7项时,第6项和第8项也将可视化,尽管它们不可见 如何限制可视化项目,从而只可视化可见项目?虚拟化是一个相当复杂的主题,但我有一本书对此进行了很好的描述。此外,本书还展示了如何实现定制虚拟化,您可能需要实现定制虚拟化来实现您的目标。幸运的是,我发现有人在网上发布了这本书的PDF文件,你可以通过点击找到它 虚拟化部分从第129页开始,但它的其余部分也值得一读,因为其中有一些非常有趣的内容。我通过覆盖MeasureOverride函数解决了这个问题,我们已经购买了She

例如:有一个列表视图,当查看第7项时,第6项和第8项也将可视化,尽管它们不可见


如何限制可视化项目,从而只可视化可见项目?

虚拟化是一个相当复杂的主题,但我有一本书对此进行了很好的描述。此外,本书还展示了如何实现定制虚拟化,您可能需要实现定制虚拟化来实现您的目标。幸运的是,我发现有人在网上发布了这本书的PDF文件,你可以通过点击找到它


虚拟化部分从第129页开始,但它的其余部分也值得一读,因为其中有一些非常有趣的内容。

我通过覆盖
MeasureOverride
函数解决了这个问题,我们已经购买了Sheridan在回答中提到的书,具体取决于虚拟化章节,下面是我对我的类所做的扩展
虚拟化StackPanel
:它成功了

private ItemsControl ItemsOwner { get; set; }
        private int StartIndex { get; set; }
        private int EndIndex { get; set; }


        protected override void OnInitialized(EventArgs e)
        {
            ItemsOwner = ItemsControl.GetItemsOwner(this) as ItemsControl;
        }


        protected override Size MeasureOverride(Size availableSize)
        {
            ItemsControl itemsControl = ItemsControl.GetItemsOwner(this);

            // we can set StartIndex& EndIndex to mimic 
            // VirtualizingStackPanel.CacheSize in .Net 4.5
            // for my problem, I just fixed them at the index of item to be shown 
            StartIndex = PagesView.Instance.SelectedIndex;
            EndIndex = StartIndex;

            // Virtualize items
            IItemContainerGenerator generator = ItemsOwner.ItemContainerGenerator;

            GeneratorPosition startPos = generator.GeneratorPositionFromIndex(StartIndex);
            int childIndex = startPos.Offset == 0 ? startPos.Index : startPos.Index + 1;
            using (generator.StartAt(startPos, GeneratorDirection.Forward, true))
            {
                for (int i = StartIndex; i <= EndIndex; i++, childIndex++)
                {
                    bool isNewlyRealized;
                    UIElement child = generator.GenerateNext(out isNewlyRealized) as UIElement;
                    if (isNewlyRealized)
                    {
                        if (childIndex >= InternalChildren.Count)
                        {
                            AddInternalChild(child);
                        }
                        else
                        {
                            InsertInternalChild(childIndex, child);
                        }
                        generator.PrepareItemContainer(child);
                    }
                }
            }



            //DumpGeneratorContent();


            // Measure
            foreach (UIElement child in InternalChildren)
            {
                child.Measure(availableSize);
            }

            // Clean up
            CleanupItems();

            return availableSize;
        }

        private void CleanupItems()
        {
            IItemContainerGenerator generator = ItemsOwner.ItemContainerGenerator;
            for (int i = InternalChildren.Count - 1; i >= 0; i--)
            {
                GeneratorPosition position = new GeneratorPosition(i, 0);
                int itemIndex = generator.IndexFromGeneratorPosition(position);
                if (itemIndex < StartIndex || itemIndex > EndIndex)
                {
                    generator.Remove(position, 1);
                    RemoveInternalChildRange(i, 1);
                }
            }
        }
private ItemsControl ItemsOwner{get;set;}
私有int StartIndex{get;set;}
私有int-EndIndex{get;set;}
已初始化受保护的覆盖无效(事件参数e)
{
ItemsOwner=ItemsControl.GetItemsOwner(this)作为ItemsControl;
}
受保护的覆盖尺寸测量覆盖(尺寸可用尺寸)
{
ItemsControl ItemsControl=ItemsControl.GetItemsOwner(this);
//我们可以将StartIndex和EndIndex设置为模拟
//.Net 4.5中的virtualzingstackpanel.CacheSize
//对于我的问题,我只是在要显示的项的索引处修复了它们
StartIndex=PagesView.Instance.SelectedIndex;
EndIndex=StartIndex;
//虚拟化项目
IItemContainerGenerator生成器=ItemsOwner.ItemContainerGenerator;
GeneratorPosition startPos=generator.GeneratorPositionFromIndex(StartIndex);
int childIndex=startPos.Offset==0?startPos.Index:startPos.Index+1;
使用(generator.StartAt(startPos,GeneratorDirection.Forward,true))
{
for(int i=StartIndex;i=InternalChildren.Count)
{
AddInternalChild(儿童);
}
其他的
{
InsertInternalChild(childIndex,child);
}
生成器。PrepareItemContainer(子级);
}
}
}
//DumpGeneratorContent();
//量
foreach(InternalChildren中的UIElement子元素)
{
儿童。测量(可用性);
}
//清理
清理项目();
返回可用性;
}
私有void CleanupItems()
{
IItemContainerGenerator生成器=ItemsOwner.ItemContainerGenerator;
对于(int i=InternalChildren.Count-1;i>=0;i--)
{
发电机位置=新的发电机位置(i,0);
int itemIndex=生成器。从生成器位置(位置)索引;
if(itemIndexEndIndex)
{
发电机。拆卸(位置1);
RemoveInternalChildRange(i,1);
}
}
}

什么是可视化?您的ListView一次只显示一个项目?如果您使用的是.Net 4.5,您可以更改名为VirtualzingStackPanel.CacheSize或类似的属性。Google it。我正在使用.Net 4.0,@Blam,我所说的可视化项目是指使用其数据模型构建其数据模板可视化树。@“dev hedgehog”virtualizengstackpanel.CacheSize正是我所需要的,现在我必须寻找一种在.Net 4.0中实现它的方法。谢谢,我已经阅读了该部分,我在VirtualizeItems方法中找到了该解决方案,但是,在我们的例子中,我们正在扩展VirtualzingStackPanel类,不幸的是,“VirtualizeItems”方法没有公开用于重写。
VirtualizeItems
方法是一个自定义方法,它不是任何基类的一部分。它内部的功能可以直接写入
MeasureOverride
方法。唯一的问题是,要使用它,您必须实现自己的虚拟化控制。这很复杂,但我做到了,所以这是可能的。如果你决定试一试的话,祝你好运。当然这很复杂,你必须明智地决定。你看到虚拟化StackPanel.CacheSize了吗?但在4.5中,迁移是另一个问题;我还没有看到这个
CacheSize
属性。。。根据MSDN上的.NET 4.5页面,它不存在。不管是哪种方式,这本书都很好地解释了如何实现自己的系统,实现自己的系统应该只需要一两个小时。