gpt4 book ai didi

c# - WPF ItemsCollection.ItemContainerGenerator 的可能竞争条件

转载 作者:行者123 更新时间:2023-11-30 16:31:45 25 4
gpt4 key购买 nike

在我的应用程序中,我需要在 ItemsSource 更改后立即获取 ItemsCollection 的内容。或者,至少,在可以视觉绘制内容之前。

我测试了一些接近于以下的东西:

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 是预期值,代码将大概工作。

附言。我还尝试在匿名函数内执行 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));
}
};

遗憾的是,行为是相同的。

编辑

我无法相信您必须为生成的内容跳过多少圈。

我相信我已经找到了可以安全地捕获生成的容器的最早时刻。但是,我仍然在这些容器内生成的内容上显示为 nil。请注意以下几点:

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 返回的容器不为空。但是,VisualTreeHelper.GetChildrenCount(container) 为 0。我仍然很想知道是否有人解决了这个问题。

最佳答案

几分钟前我遇到了同样的问题。有点不同的是,我需要元素容器的确切位置和尺寸信息。我试过你试听 StatusChanged ItemContainerGenerator 事件最后发现状态变成了ContainersGenerated并且确实生成了容器,但尚未进行布局。

所以我做了一些非常粗暴的事情。首先我设置了一个标志,比如说,_updatePending , 而 ItemContainerGenerator 的状态变成了ContainersGenerated , 然后我处理了 LayoutUpdated ItemsControl 事件,它会经常触发,以检查 _updatePending标志和元素容器是否被布置:

var firstContainer = this.ItemsContainer.ItemContainerGenerator.ContainerFromIndex(0) as FrameworkElement;
if (_updatePending
&& firstContainer != null
&& firstContainer.IsLoaded)
{
// do stuff
_updatePending = false;
}

这很残酷,但在某种程度上是有效的。

关于c# - WPF ItemsCollection.ItemContainerGenerator 的可能竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4672315/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com