在我的應用程序中,我需要在ItemsSource被更改後立即獲取ItemsCollection的內容。或者,至少在視覺化繪製內容的可能性之前。可能的WPF競態條件ItemsCollection.ItemContainerGenerator
我測試了接近如下:
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
返回容器不爲空。但是,VisualTreeHelper.GetChildrenCount(container)
是0.我仍然非常想知道是否有人解決了這個問題。
對於讀者,我會指出,我發現絕對沒有可靠的方法來引用ItemsControl中生成的內容。不惜一切代價避免這種情況。 – Kivin 2011-01-24 14:21:04