Sam*_*Sam 22 wpf listview scroll
WPF,类似浏览器的应用.
我有一个包含ListView的页面.在调用PageFunction后,我向ListView添加一行,并希望将新行滚动到视图中:
ListViewItem item = ItemContainerGenerator.ContainerFromIndex(index) as ListViewItem;
if (item != null)
ScrollIntoView(item);
Run Code Online (Sandbox Code Playgroud)
这有效.只要新线在视图中,线就会得到它应该的焦点.
问题是,当线条不可见时,事情不起作用.
如果该行不可见,则生成的行没有ListViewItem,因此ItemContainerGenerator.ContainerFromIndex返回null.
但如果没有该项目,如何将该行滚动到视图中?有没有办法滚动到最后一行(或任何地方)而不需要ListViewItem?
Sam*_*Sam 39
有人告诉我一个更好的方法滚动到一个特定的线,这很容易,就像魅力一样.
简而言之:
public void ScrollToLastItem()
{
lv.SelectedItem = lv.Items.GetItemAt(rows.Count - 1);
lv.ScrollIntoView(lv.SelectedItem);
ListViewItem item = lv.ItemContainerGenerator.ContainerFromItem(lv.SelectedItem) as ListViewItem;
item.Focus();
}
Run Code Online (Sandbox Code Playgroud)
MSDN论坛中的较长版本:
EFr*_*ank 10
我认为这里的问题是如果该行不可见,则尚未创建ListViewItem.WPF按需创建Visible.
所以在这种情况下你可能会得到null这个项目,对吗?(根据你的评论,你这样做)
我在MSDN论坛上发现了一个链接,建议直接访问Scrollviewer以便滚动.对我来说,那里提出的解决方案看起来非常像黑客,但你可以自己决定.
以下是上述链接的代码段:
VirtualizingStackPanel vsp =
(VirtualizingStackPanel)typeof(ItemsControl).InvokeMember("_itemsHost",
BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic, null,
_listView, null);
double scrollHeight = vsp.ScrollOwner.ScrollableHeight;
// itemIndex_ is index of the item which we want to show in the middle of the view
double offset = scrollHeight * itemIndex_ / _listView.Items.Count;
vsp.SetVerticalOffset(offset);
Run Code Online (Sandbox Code Playgroud)
我对Sam的回答做了一些修改.请注意,我想滚动到最后一行.不幸的是,ListView的某些内容只是显示了最后一行(即使它上面有例如100行),所以这就是我修复它的方法:
public void ScrollToLastItem()
{
if (_mainViewModel.DisplayedList.Count > 0)
{
var listView = myListView;
listView.SelectedItem = listView.Items.GetItemAt(_mainViewModel.DisplayedList.Count - 1);
listView.ScrollIntoView(listView.Items[0]);
listView.ScrollIntoView(listView.SelectedItem);
//item.Focus();
}
}
Run Code Online (Sandbox Code Playgroud)
干杯