Quelque chose d'étrange se passe avec ObservableCollection.ObservableCollection et le problème de génération de DataTemplate ListBoxItem
J'ai le code suivant:
private readonly ObservableCollection<DisplayVerse> _display;
private readonly ListBox _box;
private void TransferToDisplay()
{
double elementsHeight = 0;
_display.Clear();
for (int i = 0; i < _source.Count; i++) {
DisplayVerse verse = _source[i];
_display.Add(verse);
elementsHeight += CalculateItemsHeight(i);
if (elementsHeight + Offset > _box.ActualHeight) {
_display.RemoveAt(_display.Count - 1);
break;
}
}
MessageBox.Show(elementsHeight.ToString());
}
private double CalculateItemsHeight(int index)
{
ListBoxItem lbi = _box.ItemContainerGenerator.ContainerFromIndex(index) as ListBoxItem;
return lbi != null ? lbi.ActualHeight : 0;
}
Ce que je suis en train de faire ici est de contrôler le nombre d'éléments vont dans le _display ObservableCollection. Maintenant, dans cette boucle for, vous pouvez voir que les éléments sont ajoutés jusqu'à ce que la hauteur totale des éléments (+ offset) soit supérieure à la liste elle-même. Maintenant, cela est étrange, les élémentsHeight est égal à 0 après ceci pour la boucle. (CalculateItemsHeight renvoie 0 dans tous pour les itérations de boucle même si le lbi n'est pas nul) Il semble que les éléments d'interface utilisateur définis dans le datatemplate ne sont pas créés ...
Pourtant.
Maintenant, si je mets des MessageBox après le _display.Add (vers), vous pouvez voir que le CalculateItemsHeight retourne réellement la hauteur d'un élément.
for (int i = 0; i < _source.Count; i++) {
DisplayVerse verse = _source[i];
_display.Add(verse);
MessageBox.Show("pause"); // <----- PROBLEM?
elementsHeight += CalculateItemsHeight(i);
if (elementsHeight + Offset > _box.ActualHeight) {
_display.RemoveAt(_display.Count - 1);
break;
}
}
MessageBox.Show(elementsHeight.ToString());
Après avoir modifier la boucle comme représenté, le dernier MessageBox montre en fait la hauteur réelle pour tous les éléments transformés.
Ma question est - quand les éléments de l'interface utilisateur sont-ils réellement créés? Il semble que cela a été fait quelque part pendant l'affichage de MessageBox. Ce comportement est assez étrange pour moi, peut-être qu'il a quelque chose à voir avec le threading, pas sûr.
Ajout à l'affichage _Display ObservableCollection crée évidemment un élément immédiatement, mais pas ses éléments visuels (ils sont cependant ajoutés par la suite, je ne sais pas exactement quand). Comment puis-je faire ce même comportement sans avoir à ouvrir la boîte de message?
Non, appeler Measure() n'a pas résolu le problème. Je suppose que je devrais tempérer avec le fil de l'interface utilisateur, mais je ne sais pas quelle partie à appeler sur Thread UI ou comment. –