我正在尝试滚动到视图中,以便垂直listivew中的最后一项始终显示,但ListView.ScrollIntoView()永远不会起作用。
我试过了:
button1_Click(object sender, EventArgs e)
{
activities.Add(new Activities()
{
Time = DateTime.Now,
Message = message
});
ActivityList.ItemsSource = activities;
// Go to bottom of ListView.
ActivityList.SelectedIndex = ActivityList.Items.Count;
ActivityList.ScrollIntoView(ActivityList.SelectedIndex);
}
我也尝试过:
ActivityList.ScrollIntoView(ActivityList.Items.Count)
和ActivityList.ScrollIntoView(ActivityList.Items.Count + 1);
但没有任何效果。
请帮忙。这真的很烦人。在这种情况下,文档isn't very helpful。
答案 0 :(得分:14)
当方法需要item对象时,您将传入索引。尝试此操作滚动到所选项目。
ActivityList.ScrollIntoView(ActivityList.SelectedItem);
如果要滚动到最后一项,可以使用此
ActivityList.ScrollIntoView(ActivityList.Items[ActivityList.Items.Count - 1]);
答案 1 :(得分:8)
它与内部列表表示有关,即当您调用ScrollIntoView().
时,项目尚未到位。经过多次尝试后,这就是我最终想出来的内容似乎工作:将两个处理程序附加到每个ListBox/ListView:
<ListBox x:Name="YourList" ... Loaded="YourList_Loaded" SelectionChanged="YourList_SelectionChanged">
和
void YourList_Loaded(object sender, RoutedEventArgs e) {
if (YourList.SelectedItem != null)
YourList.ScrollIntoView(YourList.SelectedItem);
}
void YourList_SelectionChanged(object sender, SelectionChangedEventArgs e) {
if (YourList.SelectedItem != null)
YourList.ScrollIntoView(YourList.SelectedItem);
}
你不能做的第二个处理程序。设置所选项目后,您无法立即致电ScrollIntoView()
,但尚未准备就绪。您必须允许列表在实际更改项目时通知您。第一个处理程序取决于具体情况,如果在初始加载列表内容后出现选择问题,您可能也需要它。
答案 2 :(得分:3)
ActivityList.ScrollIntoView(ActivityList.Items[ActivityList.Items.Count - 1]);
的问题
和类似的“解决方案”,至少从我遇到的情况来看,当ListBox不止一次包含相同的项目时,它会跳转到它找到的第一个,即最低索引。因此,它不关心您输入的项目的索引,它只是查找该项目并选择第一项。
我还没有找到解决方案,但我现在采取的方法是插入而不是添加项目。在原始的海报案例中,我认为这将导致:
activities.Insert(0, new Activities()
{
Time = DateTime.Now,
Message = message
});
或可能:
ActivityList.Items.Insert(0, new Activities()
{
Time = DateTime.Now,
Message = message
});
这导致每个新条目都插入到顶部,因此甚至不需要调用ScrollIntoView。
答案 3 :(得分:1)
您正在分配项目的索引,列表框需要项目本身。 尝试这样的事情:
var activity = new Activities()
{
Time = DateTime.Now,
Message = message
};
activities.Add(activity);
ActivityList.ItemsSource = activities;
ActivityList.ScrollIntoView(activity);
答案 4 :(得分:1)
这是一篇旧帖子,但由于这里没有任何答案适用于我的案例,我想添加我的实现。 我在这里找到了解决方案:[https://social.msdn.microsoft.com/Forums/vstudio/en-US/8a745550-4360-4b53-85f5-032f8f46e2cc/listview-scrollintoview-not-working-with-a-observablecollection?forum=wpf][1]
((INotifyCollectionChanged)lvLogs.Items).CollectionChanged += ListView_CollectionChanged;
private void ListView_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
ScrollToEnd(this.lvLogs);
}
private void ListView_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if ((e.Action == NotifyCollectionChangedAction.Add) && (e.NewItems != null))
{
try
{
ScrollToEnd(this.lvLogs);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), "Error updating list view", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
}
public void ScrollToEnd(ListView _ListView)
{
ScrollViewer _ScrollViewer = GetDescendantByType(_ListView, typeof(ScrollViewer)) as ScrollViewer;
_ScrollViewer.ScrollToEnd();
}
public Visual GetDescendantByType(Visual element, Type type)
{
if (element == null) return null;
if (element.GetType() == type) return element;
Visual foundElement = null;
if (element is FrameworkElement)
{
(element as FrameworkElement).ApplyTemplate();
}
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++)
{
Visual visual = VisualTreeHelper.GetChild(element, i) as Visual;
foundElement = GetDescendantByType(visual, type);
if (foundElement != null)
break;
}
return foundElement;
}
对我来说,它很完美。
答案 5 :(得分:0)
我遇到的问题与此类似。我正在以编程方式添加到ListBox,并且需要添加的最后一项是可见的。在绑定各种方法后,我发现以下是最简单和最好的
lstbox.Items.MoveCurrentToLast();
lstbox.ScrollIntoView(lstbox.Items.CurrentItem);
答案 6 :(得分:0)
这是一篇旧帖子,但我在Windows应用商店应用中遇到了同样的问题,发现以下情况有效:
private void PagesListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
pageListView.UpdateLayout();
pageListView.ScrollIntoView(pageListView.SelectedItem);
}
干杯, 保罗
答案 7 :(得分:0)
只需调用方法UpdateLayout ...
UpdateLayout();
ActivityList.ScrollIntoView(ActivityList.Items[ActivityList.Items.Count - 1]);
这会有用......
或者更简单的方法...只需编译应用程序:)它将在没有UpdateLayot()
的情况下运行答案 8 :(得分:0)
我不确定该主题是否仍然令人感兴趣,但是我无法使用上述选项在我的LISTBOX上使用。 我在某处读到不一样的项目大小也停止了滚动工作。 我确实获得了下面的Powershell代码; “ UpdateLayout()”似乎至关重要:
$zItemsCount = $ListBox.Items.Count - 1
Write-Host -ForegroundColor Cyan "ListBox Items Count - 1:" $zItemsCount
(0..$zItemsCount) | ForEach-Object {
$ListBox.SelectedIndex = $_
$ListBox.UpdateLayout()
$ListBox.ScrollIntoView($ListBox.SelectedItem)
}#-EndOf: each item -----
答案 9 :(得分:0)
根据键盘P 在13年6月5日14:37此处声明的内容:https://stackoverflow.com/a/16942650/2717521
如果仍然不起作用,请尝试调用ActivityList.UpdateLayout();。就在ScrollIntoView方法之前。
我最初想到的是相同的DataGrid之间有一个类似的问题。第一个将ScrollIntoView毫无问题,第二个则无论如何都拒绝这样做,除非我触发了UpdateLayout。事实证明,我还在对第二个DataGrid进行分组:
mycollection.GroupDescriptions.Clear();
mycollection.GroupDescriptions.Add(new PropertyGroupDescription("PART"));
datagrid_parts.ItemsSource = mycollection.View;
显然,如果您的DataGrid正在分组,则ScrollViewer无法获得正确的“可视”空间,因为某些可见区域保留在Group as GroupItem中。参考:https://social.msdn.microsoft.com/Forums/vstudio/en-US/b809f5ae-08e7-415f-9e86-fc0086cb49e7/datagrid-scrollintoview-does-not-bring-given-item-into-view-when-using-virtualization-and-grouping?forum=wpf
答案 10 :(得分:0)
发生这种情况的另一个原因是项目已被 ItemsPanel 虚拟化,默认情况下是 VirtualizingStackPanel。如果您不需要虚拟化,因为您只有相对较少的项目,那么您可以使用普通的 StackPanel 作为您的 ItemsPanel。
<ListBox>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ListBox>