Что-то странное происходит с ObservableCollection.
У меня есть следующий код:
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;
}
То, что я пытаюсь сделать здесь, - это контролировать, сколько элементов попадает в ObservableCollection _display. Теперь внутри цикла for вы можете видеть, что элементы добавляются до тех пор, пока общая высота элементов (+ смещение) не станет больше самого списка.
Теперь, это странно, elementsHeight равен 0 после этого цикла for. (CalculateItemsHeight возвращает 0 для всех итераций цикла, даже если значение lbi не равно нулю) Кажется, что элементы пользовательского интерфейса, определенные в шаблоне данных, не создаются ...
Тем не менее.
Теперь, если я добавлю несколько MessageBoxes после _display.Add (verse), вы увидите, что CalculateItemsHeight действительно возвращает высоту элемента.
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());
После того, как я изменил цикл for, как показано, последний MessageBox фактически показывает фактическую высоту для всех обработанных элементов.
Мой вопрос - когда элементы пользовательского интерфейса действительно создаются ? Кажется, что это было сделано где-то во время отображения MessageBox. Такое поведение довольно странно для меня, может быть, это как-то связано с многопоточностью, не уверен.
При добавлении в _display ObservableCollection, очевидно, сразу создает элемент, но не его визуальные элементы (однако они добавляются впоследствии, я просто не знаю точно, когда). Как я могу сделать то же самое поведение без всплывающего окна сообщения?