Dans mon application, j'ai besoin d'acquérir le contenu d'un ItemsCollection immédiatement après la modification de ItemsSource. Ou, à tout le moins, avant la possibilité que le contenu soit dessiné visuellement.Condition de concurrence possible avec WPF ItemsCollection.ItemContainerGenerator
J'ai testé quelque chose proche de ce qui suit:
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));
}
}
Le problème est que, au point DoSomething est appelé, la valeur de VisualTreeHelper.GetChildrenCount(container)
est 0
. Si ce code est appelé à un moment ultérieur, par exemple en réponse à un tir d'événement Button.Click
, VisualTreeHelper.GetChildrenCount
est la valeur attendue et le code fonctionnera probablement.
PS. J'ai également essayé de conduire la boucle while à l'intérieur d'une fonction anonyme:
this.itemsControl.ItemContainerGenerator.ItemsChanged += (_sender, _ea) => {
int ctrIndex = 0;
DependencyObject container;
while((container = this.itemsControl.ItemContainerGenerator.
ContainerFromIndex(ctrIndex++)) != null) {
DoSomething(VisualTreeHelper.GetChild(container, 0));
}
};
Le comportement est identique, malheureusement.
modifier
Je ne peux pas croire combien de cerceaux vous devez sauter à travers pour le contenu généré.
Je crois que j'ai trouvé le premier moment que je peux capturer en toute sécurité les conteneurs générés. Cependant, je suis toujours en train d'augmenter zéro sur le contenu généré à l'intérieur de ces conteneurs. Respectez les consignes suivantes:
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();
}
}
Au est appelé le point DoStuff(), les contenants retournés de ContainerFromIndex
ne sont pas nulles. Cependant, VisualTreeHelper.GetChildrenCount(container)
est 0. J'aimerais toujours beaucoup savoir si quelqu'un a résolu cela.
Pour les lecteurs, je ferai remarquer que je n'ai trouvé absolument aucun moyen fiable de référencer le contenu généré dans un ItemsControl. Évitez cela à tout prix. – Kivin