在我的应用程序中,我需要在更改ItemsCollection之后立即获取ItemsSource的内容。或者,至少,在内容被视觉绘制的可能性之前。
我测试了一些接近以下内容的内容:
void UserControl_Loaded(object sender, EventArgs eventArgs) {
this.itemsControl.ItemsSource = GetItemsSource();
int ctrIndex = 0;
DependencyObject container;
while((container = this.itemsControl.ItemContainerGenerator.
ContainerFromIndex(ctrIndex++)) != null) {
DoSomething(VisualTreeHelper.GetChild(container, 0));
}
}问题是,在调用DoSomething时,VisualTreeHelper.GetChildrenCount(container)的值是0。如果在稍后的某个时间点调用此代码--例如响应Button.Click事件触发,则VisualTreeHelper.GetChildrenCount是预期值,并且该代码可能会工作。
PS。我还尝试在匿名函数的内部执行while循环:
this.itemsControl.ItemContainerGenerator.ItemsChanged += (_sender, _ea) => {
int ctrIndex = 0;
DependencyObject container;
while((container = this.itemsControl.ItemContainerGenerator.
ContainerFromIndex(ctrIndex++)) != null) {
DoSomething(VisualTreeHelper.GetChild(container, 0));
}
};不幸的是,这种行为是一样的。
编辑
我真不敢相信你要跳过多少圈才能得到生成的内容。
我相信我已经找到了能够安全捕获生成的容器的最早时刻。但是,我仍然对这些容器中生成的内容显示为零。观察以下情况:
this.itemsControl.ItemContainerGenerator.StatusChanged += new EventHandler(StatusChanged);
void StatusChanged(object sender, EventArgs e) {
var cg = this.itemsControl.ItemContainerGenerator;
if(cg.Status == GeneratorStatus.ContainersGenerated && cg.ContainerFromIndex(0) != null) {
DoStuff();
}
}在调用DoStuff()时,从ContainerFromIndex返回的容器不是null。然而,VisualTreeHelper.GetChildrenCount(container)是0。我还是很想知道是否有人解决了这个问题。
发布于 2013-10-30 12:40:08
几分钟前我遇到了同样的问题。一些小的区别是,我需要准确的位置和大小的信息的项目容器。我试着听一听ItemContainerGenerator的ItemContainerGenerator事件,最后发现虽然状态变成了ContainersGenerated,容器确实生成了,但它们还没有布局。
所以我做了件很粗暴的事。首先,我设置了一个标志,比如_updatePending,而ItemContainerGenerator的状态变成了ContainersGenerated,然后我处理了ItemsControl的LayoutUpdated事件,这个事件会频繁地触发,以检查_updatePending标志以及项目容器是否布局:
var firstContainer = this.ItemsContainer.ItemContainerGenerator.ContainerFromIndex(0) as FrameworkElement;
if (_updatePending
&& firstContainer != null
&& firstContainer.IsLoaded)
{
// do stuff
_updatePending = false;
}这是残酷的,但某种程度上是有效的。
发布于 2011-01-12 18:17:22
问题是,在对集合进行更改时,不能对其进行迭代。克服这一问题的一种方法是在填充数据之后直接查看ItemsSource对象,而不是在控件上迭代ItemsSource。如果使用的是MVVVM模式,则应该能够在ViewModel中填充集合属性(绑定到控件的ViewModel中的属性),并在从数据库/服务返回数据后检查该属性。
https://stackoverflow.com/questions/4672315
复制相似问题