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 在所有 for 循环迭代中返回 0,即使 lbi 不为空)似乎未创建数据模板中定义的 UI 元素...
Yet.
现在,如果我在 _display.Add(verse) 之后放置一些 MessageBox,您可以看到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实际上显示所有已处理元素的实际高度。
我的问题是 -UI 元素何时实际创建?看起来它是在 MessageBox 显示期间的某个地方完成的。这种行为对我来说很奇怪,也许它与线程有关,不确定。
添加到 _display ObservableCollection 显然会立即创建一个项目,但不会创建其视觉元素(但是它们是在之后添加的,我只是不知道确切的时间)。我怎样才能在不弹出消息框的情况下执行相同的行为?