我有一门课叫书;
class Book
{
public string Name { get; set; }
public string Author { get; set; }
public int PagesCount { get; set; }
public int Category { get; set; }
}
ListBox 显示书籍列表,并且 ItemTemplate 已被修改,以便直观地表示书籍。文字显示书名、作者和页数。然而,类别由某种颜色表示(例如,历史是蓝色,浪漫是红色等)。现在,文本具有 OuterGlowBitmap 效果和从类别 (int) 到适当颜色的值转换器。ListBoxItem 的所有内容都绑定在 DataTemplate 中。从技术上讲,一切正常。
然而,问题在于性能。似乎 outerGlow 位图效果在处理器上很重,所以当我有一个大约 500 本书的列表时,从数据库中检索数据大约需要 500 毫秒,但将项目实际加载到 ListBox 大约需要 10 秒。即使加载完成,滚动也很慢。我尝试将 VirtualizingStackPanel.IsVirtualizing 设置为 True,但无济于事。(在任何给定时间,数据库中的最大书籍数量约为 30000。)
但是,即使列表框中有 100 多个项目,人脑也无法快速处理,因此我的目标不是加载并向用户列出所有搜索到的书籍。这就是为什么我创建了一个包装导航类 BookNavigator,它实际上将列表框绑定到它的 ObservableCollection 对象。所有书籍都加载到此 BookNavigator 中,但只有 X 本书显示在列表框中(通过将它们添加到 observableCollection 中)。
这样做的问题是我希望显示的书籍数量足够小,以至于列表框不显示滚动条,所以我可以实现自己的滚动方法(第一个、上一个、下一个、最后一个,或者只是我自己的滚动条,不没关系)。
如何计算要显示的项目数,以便不显示滚动条?
弹出的两个问题: - 调整应用程序的大小可以更改列表框的大小 - 并非所有列表框项目的高度都相同(取决于作者的数量)。
有什么办法可以实现我想要做的事情吗?
编辑(作为对马丁哈里斯的回复)
Martin Harris 建议的代码的问题是 foreach 循环使用 FrameworkElement,但列表框填充了 Book 类型的对象,这些对象不继承自 FrameworkElement,也没有任何其他计算其高度的方法。ListBoxItem 的根元素是一个网格,所以也许可以检索这个网格,但我不知道该怎么做?
有什么方法可以获取为表示列表框项而创建的实际 UI 元素?
编辑
我发现这个 Q/A 似乎是我需要的.. ItemContainerGenerator