ObservableCollection和ListBoxItem DataTemplate生成问题
ObservableCollection正在发生一些奇怪的事情。
我有以下代码:
private readonly ObservableCollection _display; private readonly ListBox _box; private void TransferToDisplay() { double elementsHeight = 0; _display.Clear(); for (int i = 0; i _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。 (即使lbi不为null,CalculateItemsHeight在所有for循环迭代中返回0)似乎没有创建datatemplate中定义的UI元素…
然而。
现在,如果我在_display.Add(经文)之后添加了一些MessageBox,你可以看到CalculateItemsHeight实际上返回了一个项目的高度。
for (int i = 0; i < _source.Count; i++) { DisplayVerse verse = _source[i]; _display.Add(verse); MessageBox.Show("pause"); // _box.ActualHeight) { _display.RemoveAt(_display.Count - 1); break; } } MessageBox.Show(elementsHeight.ToString());
在修改了如图所示的for循环后,最后一个MessageBox 实际显示了所有已处理元素的实际高度。
我的问题是 – UI元素何时实际创建 ? 它似乎是在MessageBox显示期间的某个地方完成的。 这种行为对我来说很奇怪,也许它与线程有关,不确定。
添加到_display ObservableCollection显然会立即创建一个项目,但不会创建它的可视元素(但是之后会添加它们,我只是不确切知道何时)。 如何在不必弹出消息框的情况下执行相同的操作?
实际上,我试图让它工作,我找到了“.UpdateLayout()”函数,这对我来说非常合适。 我意识到你正在做垂直而我正在做水平,但这是我的代码,它很简单:
for (int i = 0; i < listOfItems.ItemsIn.Count; ++i) { //CalculateItemsHeight(i); ListBoxItem abc = (lb.ItemContainerGenerator.ContainerFromItem(lb.Items[i]) as ListBoxItem); abc.UpdateLayout(); totalWidth += abc.ActualWidth; }
希望这有帮助!
wpf布局引擎不会通过布局和排列传递,所以你的listboxitems还没有给出大小。 粘贴在消息框中将允许执行此操作的后台线程运行。 在查看尺寸之前,请尝试强制调用Measure()。
解决了
这会在几分之一秒内产生一些闪烁效果(就像逐个装载物品一样),但实际上符合我的需要。
重点是在检索项目高度之前刷新项目的UI。
我创建了一个扩展方法:
public static void RefreshUI(this DependencyObject obj) { obj.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Loaded, (Action)delegate { }); }
然后在检索高度之前,我刷新UI。
上述就是C#学习教程:ObservableCollection和ListBoxItem DataTemplate生成问题分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注---计算机技术网(www.ctvol.com)!
private double CalculateItemsHeight(int index) { ListBoxItem lbi = _box.ItemContainerGenerator.ContainerFromIndex(index) as ListBoxItem; if (lbi != null) { lbi.RefreshUI(); return lbi.ActualHeight; } return 0; }
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/955059.html