我有一个 ListView,其中包含一堆大小不规则的项目。当您滚动 ListView 时,最后一项的底部将最终位于控件的底部:您无法继续滚动。
如果最后一项小于控件,我想要top最后一个项目能够滚动到控件的顶部(如果该项目比控件大,我对默认行为很好;在这种情况下,项目的顶部将滚动到控件的顶部) ListView控件满足我的设计)。 (这类似于 Visual Studio Code 中的行为editor.scrollBeyondLastLine
设置为 true)
I've almost已经可以工作了,但还没有完全实现。在我的尝试中,我将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()
只是一个小小的扩展方法,可以找出ScrollViewer
从任何ListView
。我在这里用它来尝试传递一些合理的东西lvi.Measure
.)
这不太有效,因为DesiredSize.Height
of the ListViewItem
最终比Height
所渲染的ListViewItem
(我不知道为什么)。
如果我知道,我实际上可以接受这种行为作为妥协DesiredSize.Height
would always比需要的要大……但我敢打赌这实际上不是真的。
所以我显然需要插入渲染管道的不同部分来管理它。但我不知道在哪里。
我应该子类化ListView's
ScrollViewer
不知何故(因为我认为ScrollViewer
是真正布置孩子的ListViewItem
控制?)?还有其他方法可以做到这一点吗?或者这根本就是不可能的?