【发布时间】:2018-01-04 21:38:48
【问题描述】:
我有一个 ListView 有一堆不规则大小的项目。当您滚动 ListView 时,最后一项的底部将最终位于控件的底部:您无法继续滚动。
如果最后一项小于控件,我希望最后一项的top能够滚动到控件顶部(如果该项大于控件,我我对默认行为很好;在这种情况下,项目的顶部将滚动到满足我设计的 ListView 控件的顶部)。 (这类似于 editor.scrollBeyondLastLine 设置为 true 的 Visual Studio Code 中的行为)
我已经几乎完成了这项工作,但还没有完成。在我的尝试中,我将ListView 子类化,这样我就可以覆盖PrepareContainerForItemOverride。
然后我尝试在项目的底部边距中添加足够的额外空间,以便项目的顶部位于 ListView 的顶部。
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
base.PrepareContainerForItemOverride(element, item);
var lvi = element as ListViewItem;
if (lvi == null) { return; }
var currentIndex = this.Items.IndexOf(item);
if (currentIndex == (this.Items.Count - 1))
{
var sv = this.ScrollViewer();
lvi.Measure(new Size(sv.ViewportWidth, double.PositiveInfinity));
var slackSpace = sv.ViewportHeight - lvi.DesiredSize.Height;
if (slackSpace > 0)
{
lvi.Margin = new Thickness(lvi.Margin.Left, lvi.Margin.Top, lvi.Margin.Right, slackSpace + lvi.Margin.Bottom);
}
}
}
}
(在这段代码中,this.ScrollViewer() 只是一个小扩展方法,可以从任何ListView 中找出ScrollViewer。我在这里使用它来尝试将一些合理的东西传递给lvi.Measure。)
这不太行,因为ListViewItem 的DesiredSize.Height 最终比渲染的ListViewItem 的Height 大一点(我不知道为什么)。
如果我知道DesiredSize.Height 会总是 比需要的大,我实际上可以忍受这种行为作为妥协...但我敢打赌这实际上不是真的。
所以我显然需要插入渲染管道的不同部分来管理它。但我不知道在哪里。
我是否应该以某种方式继承ListView's ScrollViewer(因为我认为ScrollViewer 是实际布置子ListViewItem 控件的原因?)?还有其他方法可以做到这一点吗?还是只是不可能?
【问题讨论】:
-
你能放一些视觉效果更好地理解吗?