何时为ListBox创建ListBoxItem?

时间:2010-09-10 08:06:21

标签: .net wpf listbox listboxitem

我有一个ListBox,我绑定到ItemsSource,如下所示:

var foos = new ObservableCollection<Foo> { foo1, foo2, foo3 };
var listBox = new ListBox { ItemsSource = _foos };

现在我想立即对包含项目的ListBoxItem进行一些操作,但它们似乎不会立即创建。是吗?是否有一些事件我可以收听以便收到通知,或者我只是想以无效的方式获取ListBoxItem?我这样做(并且已经验证它在我知道ListBox已经“准备好”的某个地方工作):

var lbi = listBox.ItemContainerGenerator.ContainerFromItem(foo1) as ListBoxItem;

请注意,这是在单元测试中完成的,所以我猜ListBox永远不会呈现。这就是为什么没有创建ListBoxItems?我可以以某种方式手动触发ListBoxItem的创建吗?

1 个答案:

答案 0 :(得分:3)

项目创建是异步完成的,并且根据面板,可能会发生根本不创建(virtualization)。您正在寻找的事件是ItemContainerGenerator.StatusChanged。在SO上进行谷歌搜索,你会发现很多例子。但是,直接搜索和处理这些项目可能会变得复杂。

Here是一篇非常好的文章,详细讨论了项目创建。另请参阅ancestor - 文章。

顺便说一句: 我建议你看一下MVVM模式。虽然有一点时间你放松学习它(与学习WPF的时间不相上下),它会为你节省很多时间。 Here您可以找到Jason Dolinger视频的链接,为您提供一个很好的起点。

更新:

正如评论中所承诺的,这里有一个搜索可视树的功能(仅在虚拟化关闭时可用)。

void FindChildFrameworkElementsOfType<T>(DependencyObject parent,IList<T> list) where T: FrameworkElement{             
    DependencyObject child; 
    for(int i=0;i< VisualTreeHelper.GetChildrenCount(parent);i++){             
        child = VisualTreeHelper.GetChild(parent, i); 
        if (child is T) { 
            list.Add((T)child); 
        } 
        FindChildFrameworkElementsOfType<T>(child,list); 
    } 
}