2010-09-10 71 views
1

我有我绑定到的ItemsSource一个列表框,如下所示:何时为ListBox创建ListBoxItems?

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

现在我希望做一些操作马上对持有项目ListBoxItems,但他们似乎并没有被正确的创建远。他们?是否有一些事件可以收听,或者我只是试图以无效的方式获取ListBoxItem?我做这样的(和已验证它工作的地方,我知道列表框“准备好”):

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

注意,这是在单元测试正在做,所以我想ListBox中从未呈现。这就是为什么ListBoxItems没有创建?我可以手动触发创建ListBoxItems吗?

回答

3

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

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

BTW: 我建议你看看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); 
    } 
} 
+0

Thx。将查看文章并尝试使用StatusChanged事件。我已经在使用MVVM,视频确实很棒。但是,在这种情况下,我需要回顾继承我正在处理的ListBox的自定义控件的单元测试的详细信息。 – stiank81 2010-09-10 09:08:37

+0

@ stiank81:如果列表中的项目很少,则可以使用ListBox上的VirtualizingStackPanel.IsVirtualizing =“False”禁用虚拟化。对于小数据集这不会是一个问题。根据您的单元测试,您也可以仅在单元测试时禁用虚拟化。 – HCL 2010-09-10 09:37:09

+0

是的,我只想为单元测试做到这一点,但它似乎并没有从代码中得到它。它说这是一个私有财产,但为什么我可以从xaml到达?任何想法,如果我可以以某种方式触发代码? – stiank81 2010-09-10 10:10:40