【发布时间】:2009-07-06 13:37:48
【问题描述】:
当 WPF ListView 的底层集合发生变化时如何正确调整滚动条的大小?
我有一个 WPF ListView 绑定到包含数千个项目的可观察集合。当大量这些被删除时,视图似乎只显示最后一项。当我使用拇指栏移动视图中的位置时,拇指栏会调整大小以反映新的集合大小。集合变化时是否可以强制 ListView 和滚动条同步?
【问题讨论】:
当 WPF ListView 的底层集合发生变化时如何正确调整滚动条的大小?
我有一个 WPF ListView 绑定到包含数千个项目的可观察集合。当大量这些被删除时,视图似乎只显示最后一项。当我使用拇指栏移动视图中的位置时,拇指栏会调整大小以反映新的集合大小。集合变化时是否可以强制 ListView 和滚动条同步?
【问题讨论】:
如果其他人有这个问题,我已经找到了解决方法。
以下代码示例显示了在第一行更改的 ListView 的项目源。以下几行显示了只是滚动回第一项的解决方法。
this.ListViewResults.ItemsSource = this.itemsFiltered;
object firstItem = this.ListViewResults.Items.GetItemAt(0);
if(firstItem == null)
{
return;
}
this.ListViewResults.ScrollIntoView(firstItem);
【讨论】:
奇怪的行为!!
我会尝试将 ListView 的绑定上下文 (Context) 设置为 null,然后再次设置相同的列表以刷新绑定。
【讨论】:
MyListView.DataContext 设置为null 和一个空白数据集。
我有一个不同的解决方法,它需要子类化 ListView。这需要更多的工作,但结果比仅滚动到第一项要好。但是您需要调整 ListView 模板,以便模板中的 ScrollViewer 有一个名称(此处为 PART_ScrollViewer),或者您使用其他方式获取 ScrollViewer 对象。
public class BetterListView : ListView
{
ScrollViewer sv;
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
//Get the scrollviewer in the template (I adapted the ListView template such that the ScrollViewer has a name property)
sv = (this.Template.FindName("PART_ScrollViewer", this)) as ScrollViewer;
}
protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
{
base.OnItemsChanged(e);
//Prevent the bug where the ListView doesn't scroll correctly when a lot of items are removed
if (sv != null && e.Action == NotifyCollectionChangedAction.Remove)
{
sv.InvalidateScrollInfo();
}
}
}
【讨论】: