我有一个ListView,它在开头就是空的。然后我不断向ListView添加项目。在某些时候,所有项目都填满了整个可用空间,从那里我想将ListView滚动到刚刚添加的项目。
通常,可以通过调用ListViewItem.BringIntoView
或ListView.ScrollIntoView(ListViewItem)
来完成此操作。
但是,ListView绑定到ListCollectionView,而Source的源是ViewModel项的ObservableCollection。所以,我正在将ViewModel项添加到该集合中。然后通过绑定创建视图项。
由于项目位于可见区域之外,因此不会立即创建ListViewItem,更不用说了。如果滚动视图靠近ListView的底部,ListViewItem将在不久之后创建并实现。 1
如果滚动视图位于ListView中间的某个位置,则它根本不起作用。
将IsVirtualizing
设置为false可以解决问题,因为无论如何都会创建并实现该项目。但这显然有一些性能下降。
所以,我正试图找到一种方法,以便创建和实现刚刚添加到集合中的项目,并最终可以进入视图。
是否有人知道如何处理此问题?
1 如果滚动视图关闭到底部,它基本上可以工作,但有一个奇怪的行为,似乎只有每个其他ListViewItem进入视图。
答案 0 :(得分:1)
VirtualizationPanel有一个方法BringIndexIntoViewPublic,可以生成项目并使其可见。
以下是所有相关代码的示例。
public class ListView_ViewModel
{
private CollectionViewSource _collectionViewSource;
private ObservableCollection<ListViewItem_ViewModel> _listViewItemViewModels;
private ListView _listView;
private void AddItem()
{
var newListViewItemViewModel = new ListViewItem_ViewModel();
_listViewItemViewModels.Add(newListViewItemViewModel);
var indexOfNewItem = _collectionViewSource.View.Cast<ListViewItem_ViewModel>()
.ToList().IndexOf(newListViewItemViewModel);
var virtualizingPanel = VisualTreeHelper.FindChild<VirtualizingPanel>(_listView);
virtualizingPanel.BringIndexIntoViewPublic(indexOfNewItem);
}
}
答案 1 :(得分:0)
根据您的问题很难说出确切的问题。但是,这可能是因为Equals
函数的行为。考虑这个结构:
<DockPanel>
<Button Name="addItem" Click="addItem_Click" Content="Add new and scroll" DockPanel.Dock="Bottom"/>
<ListView Name="sv" ScrollViewer.VerticalScrollBarVisibility="Visible">
</ListView>
</DockPanel>
有一个按钮试图添加新项目并滚动到最后。
如果添加不同的项目,它将起作用:
private void addItem_Click(object sender, RoutedEventArgs e)
{
if (sv.ItemsSource == null)
sv.ItemsSource = new ObservableCollection<string>();
string newitem = "new item" + (sv.Items.Count + 1).ToString();
((ObservableCollection<string>)sv.ItemsSource).Add(newitem);
sv.ScrollIntoView(newitem);
}
请注意,字符串永远不会相等(请参阅(sv.Items.Count + 1).ToString()
部分)。但是,这不起作用:
private void addItem_Click(object sender, RoutedEventArgs e)
{
if (sv.ItemsSource == null)
sv.ItemsSource = new ObservableCollection<string>();
string newitem = "new item";
((ObservableCollection<string>)sv.ItemsSource).Add(newitem);
sv.ScrollIntoView(newitem);
}
因为Equals
会返回第一个项目。