当前位置:  开发笔记 > 运维 > 正文

强制WPF在ItemsControl中创建项目

如何解决《强制WPF在ItemsControl中创建项目》经验,为你挑选了0个好方法。

我想验证我的项目ListBox是否在UI中正确显示.我认为这样做的一种方法是遍历ListBox视觉树中的所有孩子,获取他们的文本,然后将其与我期望的文本进行比较.

这种方法的问题是内部ListBox使用a VirtualizingStackPanel来显示其项目,因此只创建可见的项目.我最终遇到了这个ItemContainerGenerator类,它看起来应该强制WPF在可视树中为指定项创建控件.不幸的是,这对我造成了一些奇怪的副作用.这是我生成以下所有项目的代码ListBox:

List generatedItems = new List();
IItemContainerGenerator generator = this.ItemsListBox.ItemContainerGenerator;
GeneratorPosition pos = generator.GeneratorPositionFromIndex(-1);
using(generator.StartAt(pos, GeneratorDirection.Forward))
{
    bool isNewlyRealized;
    for(int i = 0; i < this.ItemsListBox.Items.Count; i++)
    {
        isNewlyRealized = false;
        DependencyObject cntr = generator.GenerateNext(out isNewlyRealized);
        if(isNewlyRealized)
        {
            generator.PrepareItemContainer(cntr);
        }

        string itemText = GetControlText(cntr);
        generatedItems.Add(itemText);
    }
}

(GetItemText()如果你愿意,我可以提供代码,但它只是遍历可视树,直到TextBlock找到它.我意识到还有其他方法可以在项目中包含文本,但是一旦我得到项目,我会解决这个问题一代人正常工作.)

在我的应用程序中,ItemsListBox包含20个项目,最初的12个项目最初可见.前14项的文本是正确的(可能是因为它们的控件已经生成).但是,对于第15-20项,我根本没有任何文字.另外,如果我滚动到底部ItemsListBox,项目15-20的文本也是空白的.因此,我似乎正在干扰WPF生成控件的常规机制.

我究竟做错了什么?是否有一种不同/更好的方法可以强制将项ItemsControl添加到可视树中?

更新:我认为我已经找到了为什么会发生这种情况,虽然我不知道如何解决它.我假设调用PrepareItemContainer()将生成任何必要的控件来显示项目,然后将容器添加到可视树中的正确位置.事实证明,它没有做这两件事.容器没有被添加到ItemsControl直到我向下滚动才能查看它,并且在那时只ListBoxItem创建了容器本身(即) - 它的子节点没有被创建(这里应该添加一些控件,其中一个应该是在TextBlock将显示该项目的文本).

如果我遍历控件的可视树,我传递给PrepareItemContainer()结果是相同的.在这两种情况下,只ListBoxItem创建了它,并且没有创建它的子节点.

我找不到添加ListBoxItem到可视树的好方法.我VirtualizingStackPanel在可视树中找到了它,但是调用了它的Children.Add()结果InvalidOperationException(不能直接添加项目ItemPanel,因为它为它生成了项目ItemsControl).就像测试一样,我尝试AddVisualChild()使用Reflection 调用它(因为它受到保护),但这也没有用.

推荐阅读
php
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有