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