Roh*_*hit 9 wpf virtualization listbox scrollviewer actualheight
两者都是相当笼统的术语,但我很想知道这些高度何时会与我们使用虚拟化的情况不同?
还有一个问题:我在MSDN上阅读:
如果CanContentScroll为true,则ExtentHeight,ScrollableHeight,ViewportHeight和VerticalOffset属性的值是项目数.如果CanContentScroll为false,则这些属性的值为"设备无关像素".
但是我遇到了ViewPort Height的问题:我在应用程序中有2个列表框:
1.启用了虚拟化并且CanContentScroll = True.
2.哪些没有虚拟化,CanContentScroll = True.
在ListBox 1中,拖放视口高度达到4/5(当前可见的元素数).但是在ListBox 2中,我得到的视口高度等于列表框的实际高度.
为何如此区别?
更多的发现:
1.可滚动高度是滚动查看器2中不可见的项目数
.视口高度是滚动查看器中可见的项目数.
因此,视口高度+ ScrollableHeight =范围高度
有人可以解释两个列表框之间有什么区别吗?在Listbox 1的情况下我需要ViewPort hieght
Mar*_*ter 12
这ActualHeight是ScrollViewer的实际高度.视口是ScrollViewers内容中可见的内容.所以回答你的问题:ViewportHeight不同于ActualHeight滚动条的水平滚动条是否可见Height.
所以,总结一下:
ActualHeight = ViewportHeight + HorizontalScrollbarHeight
Run Code Online (Sandbox Code Playgroud)
最后这是根本原因:
您遇到了物理滚动和逻辑滚动之间的差异.
正如您所发现的,每个都有其权衡.
物理滚动
物理滚动(CanContentScroll = false)只是以像素为单位,因此:
视口始终表示滚动范围的完全相同部分,为您提供平滑的滚动体验,但是
DataGrid的全部内容必须完全应用所有模板,并进行测量和排列以确定滚动条的大小,导致加载期间的长时间延迟和高RAM使用率,并且它不会真正滚动项目,因此它不理解ScrollIntoView非常好逻辑滚动
逻辑滚动(CanContentScroll = true)按项而不是像素计算其滚动视口和范围,因此:
视口可以在不同时间显示不同数量的项目,这意味着视口中的项目数量与范围中的项目数量相比会发生变化,从而导致滚动条长度发生变化,以及
滚动从一个项目移动到下一个项目,从不介于两者之间,导致"生涩"滚动
但
只要您在底层使用VirtualizingStackPanel,它只需要应用模板并测量和排列此刻实际可见的项目,以及
ScrollIntoView要简单得多,因为它只需要将正确的项索引放入视图中
在他们之间选择
这是WPF提供的唯一两种滚动.您必须根据上述权衡选择它们.通常,逻辑滚动最适合中型到大型数据集,物理滚动最适合小型数据集.
物理滚动期间加速加载的一个技巧是使物理滚动更好的方法是将项目包装在具有固定大小的自定义装饰器中,并在不可见时将其子项的可见性设置为隐藏.这可以防止ApplyTemplate,Measure和Arrange在该项的后代控件上发生,直到您准备好它为止.
使物理滚动的ScrollIntoView更可靠的一个技巧是调用它两次:一次在DispatcherPriority.ApplicationIdle的调度程序回调中立即执行一次.
使逻辑滚动滚动条更稳定
如果所有项目的高度相同,则视口中随时可见的项目数将保持不变,从而导致滚动缩略图大小保持不变(因为如果项目未更改,则与总数的比率).
也可以修改ScrollBar本身的行为,以便始终将拇指计算为固定大小.要做到这一点,没有任何hacky代码隐藏:
更改用于
逻辑滚动ScrollBar 的ScrollBar模板
以使用子类轨道而不是常规轨道
更改ScrollViewer模板以在逻辑滚动ScrollBar上显式设置自定义ScrollBar模板
(而不是使用默认
模板)
这意味着在内置的WPF模板中复制了大量的模板代码,因此它不是一个非常优雅的解决方案.但是替代方法是使用hacky代码隐藏等待所有模板扩展,然后找到ScrollBar并将ScrollBar模板替换为使用自定义Track的模板.此代码以一些非常棘手的代码为代价保存了两个大型模板(ListBox,ScrollViewer).
使用不同的Panel会有更多的工作量:VirtualizingStackPanel是唯一虚拟化的Panel,只有它和StackPanel才能进行逻辑滚动.由于您正在利用VirtualizingStackPanel的虚拟化功能,因此您必须重新实现所有这些以及所有IScrollInfo信息功能以及常规Panel功能.我可以做类似的事情,但我会分配好几天,也许很多天才能做到.我建议你不要尝试.
礼貌 - 物理滚动与逻辑滚动
| 归档时间: |
|
| 查看次数: |
20413 次 |
| 最近记录: |